33

我有一套那种结构。我没有重复,但是当我调用时: set.add(element)-> 并且已经有确切的元素,我希望替换旧的元素。

import java.io.*;

public class WordInfo implements Serializable {
    File plik;
    Integer wystapienia;

    public WordInfo(File plik, Integer wystapienia) {
        this.plik = plik;
        this.wystapienia = wystapienia;
    }

    public String toString() {
    //  if (plik.getAbsolutePath().contains("src") && wystapienia != 0)
            return plik.getAbsolutePath() + "\tWYSTAPIEN " + wystapienia;
    //  return "";
    }
    @Override
    public boolean equals(Object obj) {
        if(this == obj) return true;
        if(!(obj instanceof WordInfo)) return false;
        return this.plik.equals(((WordInfo) obj).plik);
    }

    @Override
    public int hashCode() {        
        return this.plik.hashCode();
    }
}
4

5 回答 5

60

在每次添加之前进行删除:

 someSet.remove(myObject);
 someSet.add(myObject);

删除将删除任何等于 myObject 的对象。或者,您可以检查添加结果:

 if(!someSet.add(myObject)) {
     someSet.remove(myObject);
     someSet.add(myObject);
 }

哪个更有效取决于您发生碰撞的频率。如果它们很少见,第二种形式通常只做一次操作,但当发生碰撞时,它会做三次。第一种形式总是做两个。

于 2012-11-19T04:18:19.463 回答
5

如果集合中已经包含equals()您尝试添加的元素的元素,则不会添加新元素,也不会替换现有元素。为了保证新元素被添加,只需先从集合中删除它:

set.remove(aWordInfo);
set.add(aWordInfo);
于 2012-11-19T04:19:25.310 回答
1

我正在解决一个问题,我有一个集合,然后我想用另一个集合中的对象替换/覆盖一些对象。

在我的情况下,我最终做的是创建一个新集并首先放置覆盖,然后添加当前对象。这是因为在添加新对象时集合不会替换任何现有对象。

如果你有:

Set<WordInfo> currentInfo;
Set<WorldInfo> overrides;

代替:

for each override, replace the object in current info

我做了:

Set<WordInfo> updated = new HashSet<>();
updated.addAll(overrides);
updated.addAll(currentInfo);
于 2018-02-12T05:29:28.070 回答
0

尝试如下操作(这仅在equalsandhashCode依赖于一个字段时才有意义,但其他字段可能具有不同的值):

if(!set.add(obj)) {
    //set already contains the element (not the same object though) 
    set.remove(obj); //remove the one in  the set
    set.add(obj); //add the new one
}

查看该Set.add方法的文档

如果该集合已包含该元素,则调用将保持该集合不变并返回 false。

于 2012-11-19T04:17:31.520 回答
-2

检查HashSetJDK中的代码。当添加一个元素并且是重复元素时,旧值将被替换。民间认为新元素被丢弃,这是错误的。因此,您不需要额外的代码。

更新 - - - - - - - - - - -

我重新阅读了 JDK 中的代码,并承认我犯了一个错误。

生成时put,VALUE 被替换,而不是 KEY 中的HashMap.

为什么我在说Hashmap??!!因为如果你看HashSet代码,你会注意到:

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

因此,该PRESENT值被替换为新值,如这部分代码所示:

      public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

但我同意,key没有被替换,并且由于keys 代表HashSet's值,所以这个被称为“未触及”。

于 2012-11-19T04:16:15.750 回答