gpt4 book ai didi

java - HashSet.remove() 和 Iterator.remove() 不起作用

转载 作者:IT老高 更新时间:2023-10-28 20:55:38 30 4
gpt4 key购买 nike

我在 HashSet 上调用 Iterator.remove() 时遇到问题。

我有一组带有时间戳的对象。在将新项目添加到集合之前,我会遍历集合,识别该数据对象的旧版本并将其删除(在添加新对象之前)。时间戳包含在 hashCode 和 equals() 中,但不包含在 equalsData() 中。

for (Iterator<DataResult> i = allResults.iterator(); i.hasNext();)
{
DataResult oldData = i.next();
if (data.equalsData(oldData))
{
i.remove();
break;
}
}
allResults.add(data)

奇怪的是,对于集合中的某些项目, i.remove() 静默失败(没有异常(exception))。我已经验证了

  • 实际上调用了 i.remove() 行。我可以直接在Eclipse的断点处从调试器调用它,它仍然无法改变Set的状态

  • DataResult 是一个不可变的对象,所以它在最初添加到集合后不能改变。

  • equals 和 hashCode() 方法使用 @Override 来确保它们是正确的方法。单元测试验证这些工作。

  • 如果我只使用 for 语句和 Set.remove 代替,这也会失败。 (例如,遍历项目,在列表中找到项目,然后在循环后调用 Set.remove(oldData))。

  • 我在 JDK 5 和 JDK 6 中测试过。

我认为我一定错过了一些基本的东西,但是在我和我的同事花了一些时间在这之后,我感到很困惑。有什么要检查的建议吗?

编辑:

有一些问题 - DataResult 真的是不可变的。是的。没有二传手。并且当检索到 Date 对象(它是一个可变对象)时,它是通过创建一个副本来完成的。

public Date getEntryTime()
{
return DateUtil.copyDate(entryTime);
}

public static Date copyDate(Date date)
{
return (date == null) ? null : new Date(date.getTime());
}

进一步编辑(稍后):记录一下——DataResult 不是一成不变的!它引用了一个对象,该对象的哈希码在持久保存到数据库时会发生变化(我知道这是不好的做法)。事实证明,如果使用临时子对象创建 DataResult,并且子对象被持久化,则 DataResult 哈希码已更改。

非常微妙——我看了很多遍,并没有注意到缺乏不变性。

最佳答案

我还是对这个很好奇,写了如下测试:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;

public class HashCodeTest {
private int hashCode = 0;

@Override public int hashCode() {
return hashCode ++;
}

public static void main(String[] args) {
Set<HashCodeTest> set = new HashSet<HashCodeTest>();

set.add(new HashCodeTest());
System.out.println(set.size());
for (Iterator<HashCodeTest> iter = set.iterator();
iter.hasNext();) {
iter.next();
iter.remove();
}
System.out.println(set.size());
}
}

导致:

1
1

如果一个对象的 hashCode() 值在添加到 HashSet 后发生了变化,它似乎使该对象不可移除。

我不确定这是否是您遇到的问题,但如果您决定重新访问,则需要考虑一下。

关于java - HashSet.remove() 和 Iterator.remove() 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/254441/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com