从Set iterator中删除

时间:2013-05-01 16:05:53

标签: java iterator

有人可以向我解释为什么以下不起作用(跑道是Hibernate PersistentSet)?

System.out.println("size before " + runways.size());
Iterator<Runway> deleteIterator = runways.iterator();
while (deleteIterator.hasNext()) {
    Runway rwy = deleteIterator.next();
    if (rwy == rwy3) {
        System.out.println("remove !");
        deleteIterator.remove();
    }
}
System.out.println("size after " + runways.size());

我得到了系统。输出日志:

INFO: size before 3
INFO: remove !
INFO: size after 3

我认为通过迭代器进行删除是安全可行的。 你看到日志“删除”!表示调用remove()方法。

编辑:PersistentSet在Iterator接口上的remove方法有问题。

4 个答案:

答案 0 :(得分:3)

检查以确保hashCode()对象上的equals()Runway方法被覆盖并正确无误。

答案 1 :(得分:3)

//编辑:仅供参考此代码是代码失败的示例。正确覆盖您的equals()hashCode()

要跟进JustinKSU的观点,如果你没有很好地实施hashCode()equals(),那么你所做的就行不通了。如果我弄乱了equals()hashCode()

,我可以复制您的情况
public static void main(String[] args) {
    Set<Runway> runways = new HashSet<Runway>();
    Runway rwy1 = new Runway();
    Runway rwy2 = new Runway();
    Runway rwy3 = new Runway();
    runways.add(rwy1);
    runways.add(rwy2);
    runways.add(rwy3);
    System.out.println("size before " + runways.size());
    Iterator<Runway> deleteIterator = runways.iterator();
    while (deleteIterator.hasNext()) {
        Runway rwy = deleteIterator.next();
        if (rwy == rwy3) {
            System.out.println("remove !");
            deleteIterator.remove();
        }
    }
    System.out.println("size after " + runways.size());
}

private static class Runway {
    @Override
    public boolean equals(Object obj) {
        return false;
    }

    @Override
    public int hashCode() {
        return (new Random()).nextInt();
    }
}

答案 2 :(得分:0)

从查看JDK源代码(我发现它here),HashSet返回的迭代器使用HashSet的内部删除方法之一来执行实际的删除

要使HashSet正常工作,您需要将equalshashCode单独留在Runway课程中,或同时覆盖它们。这个SO问题讨论了这个问题:What issues should be considered when overriding equals and hashCode in Java?

答案 3 :(得分:0)

我的equals和hashCode方法是由Eclipse自己创建的。所以它不是来自他们。

但是在我的问题开始时我太快了。我忘了Runways是来自Hibernate的PersistentSet(而不是java.util.HashSet)

我发现这个bug解释了为什么不能从PersistenSet迭代器中删除对象的原因。

这个bug看起来很古老而且很复杂。 我唯一的选择是从第一个重新创建一个集合,没有我不想要的元素。