-1

有人可以向我解释为什么以下方法不起作用(跑道是 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());

我得到了 system.Out 日志:

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

我认为通过迭代器删除是安全且可能的。您会看到日志“删除”!这表示调用了 remove() 方法。

编辑: PersistentSet 与 Iterator 接口中的 remove 方法有问题。

4

4 回答 4

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();
    }
}
于 2013-05-01T16:33:25.713 回答
3

检查以确保您的hashCode()equals()方法在您的Runway对象上被覆盖和正确。

于 2013-05-01T16:11:37.867 回答
0

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

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

我发现了这个错误,它解释了为什么不能从 PersistenSet 迭代器中删除对象。

该错误似乎很老且难以解决。然后,我唯一的选择是从第一个集合中重新创建一个集合,并且没有我不想要的元素。

于 2013-05-01T16:56:12.133 回答
0

通过查看 JDK 源代码(我在此处找到), a 返回的迭代器HashSet使用HashSet的内部删除方法之一来执行实际删除。

要使 aHashSet正常工作,您需要将两者都留equalshashCode课堂Runway上,或者将它们都覆盖。这个SO question谈到了这个问题:在Java中覆盖equals和hashCode时应该考虑哪些问题?

于 2013-05-01T16:47:34.950 回答