JDK 1.6和1.7之间的迭代器差异

时间:2013-11-29 11:30:46

标签: java jdk1.6

我遇到了在两个不同版本的JDK上运行相同代码的问题。 代码基本上在同一个HashMap上嵌套了迭代器。 以下是伪代码。我继承了这段代码......

Iterator entries = source.entrySet().iterator();
while(entries.hasNext()) {
    Map.Entry entry = entries.next();

    Iterator otherEntries = source.entrySet().iterator();
    while(otherEntries.hasNext()) {
        Map.Entry otherEntry = otherEntries.next();
        List elements = otherEntry.getValue();

        for(element : elements) {
            ...
        }

        for(someOtherElement : someOtherElement) { 
            if(...) {
                elements.add(someOtherElement);
            }
        }
    }
}

对于这段代码的混乱道歉,但正如我所提到的,我继承了这一点。 这个代码在JDK 1.7中运行正常。 在JDK 1.6(IBM RSA JDK)中,对“elements.add(...)”的调用也将元素添加到原始“源”HashMaps元素中。 “elements”列表来自otherEntry.getValue()。添加或更新元素似乎会导致源更新,因为它是通过引用传递的。 但是,在JDK 1.7(只是标准的)中,我们看不到相同的行为。这里对“elements.add”的调用不会更新或修改“源”HashMap。

所以我试着理解这里发生了什么,这是JDK之间发生的变化吗?

由于

2 个答案:

答案 0 :(得分:3)

传递实例的方式的行为没有变化。但是,您是否看到修改后的列表元素的问题取决于迭代顺序:只有在修改了外部Iterator尚未看到的条目中包含的列表时,才会看到修改后的列表。由于迭代顺序可能在不同的HashMap实现之间发生变化,因此您可能真的会在一个JDK中看到修改后的列表而不是另一个JDK。

最重要的是你不应该使用这种嵌套的Iterator。在第一个循环完成后,在一个循环中进行修改并在另一个循环中查看它时,您将可靠地看到修改后的列表。

答案 1 :(得分:0)

我从源代码中看到的唯一变化是

添加了三个新方法Collections

Collections.emptyIterator
Collections.emptyEnumeration
Collections.emptyListIterator