替换哈希集Java成员

替换哈希集Java成员,java,replace,set,duplicates,Java,Replace,Set,Duplicates,我有一套这样的结构。我没有副本,但当我调用时: set.add(element)->并且已经有了我想要替换的元素 import java.io.*; public class WordInfo implements Serializable { File plik; Integer wystapienia; public WordInfo(File plik, Integer wystapienia) { this.plik = plik;

我有一套这样的结构。我没有副本,但当我调用时:
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();
    }
}

检查JDK中的
HashSet
代码。 当添加一个重复的元素时,旧值将被替换。 人们认为新元素被丢弃了,这是错误的。 因此,在您的案例中不需要额外的代码

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

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

当执行
put
时,值将被替换,而不是
HashMap
中的键

为什么我说的是Hashmap??!!因为如果查看
哈希集
代码,您会注意到:

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;
    }
public V put(K键,V值){
if(key==null)
返回putForNullKey(值);
int hash=散列(键);
int i=indexFor(散列,table.length);
for(条目e=表[i];e!=null;e=e.next){
对象k;
如果(e.hash==hash&((k=e.key)==key | | key.equals(k))){
V oldValue=e.value;
e、 价值=价值;
e、 记录存取(本);
返回旧值;
}
}
modCount++;
加法器(散列、键、值、i);
返回null;
}
但是我同意,
没有被替换,而且由于
s代表
散列集的
值,所以这一个被称为“未触及”。

尝试如下操作(只有当
等于
散列码
依赖于一个字段时,这才有意义,但其他字段可能有不同的值):

查看该方法的文档

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


在每次添加之前执行删除操作:

 someSet.remove(myObject);
 someSet.add(myObject);
移除将移除与myObject相等的任何对象。或者,您可以检查添加结果:

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

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

如果集合中已包含一个元素,该元素
等于您尝试添加的元素()
,则不会添加新元素,也不会替换现有元素。要确保添加新元素,只需先将其从集合中移除:

set.remove(aWordInfo);
set.add(aWordInfo);

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

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

如果您有:

Set<WordInfo> currentInfo;
Set<WorldInfo> overrides;
我做到了:

Set<WordInfo> updated = new HashSet<>();
updated.addAll(overrides);
updated.addAll(currentInfo);
Set updated=new HashSet();
更新的.addAll(覆盖);
更新的.addAll(当前信息);


无法理解代码片段与问题之间的关系。你能解释一下,在你的代码中设置它的位置吗?另外,如果您的对象完全相同,那么为什么要替换?@YogendraSingh-OP希望能够将集合中的旧
WordInfo
替换为一个新的
equals()
旧对象,但不是同一个对象。(请注意,
equals()
测试忽略了
wystapienia
的值)@TedHopp:Thank,但是仍然
返回这个.plik.equals(((WordInfo)obj.plik)
将返回
true
,no???@YogendraSingh-我的观点是两个
WordInfo
对象可以是
equals()
,而不是
=
。当两个是
相等()
但不是
=
时,OP希望能够在
集合中用另一个替换一个。OP的问题是:如何进行替换。@TedHopp:我试图通过OP来理解问题本身,即
为什么?
,我仍然不相信这一点(可能这是伪示例)。我看到了你对
如何
的回答,这很好。我现在就离开。感谢您的输入。这是一个不应该依赖的内部实现细节。如果发生替换,则HashSet没有遵循add的Set约定:“调用保持集合不变并返回false”-1这完全是错误的:相同的hashcode并不意味着相同的对象。新元素被丢弃了!请参阅:
如果此集合已经包含元素,则调用将保持集合不变并返回false
@Bohemian我从来没有说过我在谈论相同的哈希代码。谈论相同的对象。我已经运行了一个测试,我很高兴确认HashSet确实符合集合契约,保留旧对象以防试图添加与集合中现有元素相等的对象。-1这不起作用。你总是想添加,不管是什么
set()
returnsok no-1,但是现在你的答案和Patricia的一样,她是第一个回答“正确”的人,就像一分钟前那样:)工作这导致线程“main”中出现异常java.util.ConcurrentModificationException
当与
迭代器
@威胁一起使用时,这是一个与此问题不同的问题,此问题是关于在可以调用
add
的情况下更改其行为。我建议把它作为一个新问题来问,背景要比你在评论中能说的更多,除非你能找到对你有帮助的现有问题。嗯,那么我们可以使用简单的
List
而不是
Set
第二块代码中的if语句可以简化为
if(someSet.remove(myObject))如果集合中存在
myObject
,则
remove
方法也会返回true。我还认为
conta
for each override, replace the object in current info
Set<WordInfo> updated = new HashSet<>();
updated.addAll(overrides);
updated.addAll(currentInfo);