我遇到了在两个不同版本的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之间发生的变化吗?
由于
答案 0 :(得分:3)
传递实例的方式的行为没有变化。但是,您是否看到修改后的列表元素的问题取决于迭代顺序:只有在修改了外部Iterator
尚未看到的条目中包含的列表时,才会看到修改后的列表。由于迭代顺序可能在不同的HashMap
实现之间发生变化,因此您可能真的会在一个JDK中看到修改后的列表而不是另一个JDK。
最重要的是你不应该使用这种嵌套的Iterator
。在第一个循环完成后,在一个循环中进行修改并在另一个循环中查看它时,您将可靠地看到修改后的列表。
答案 1 :(得分:0)
我从源代码中看到的唯一变化是
添加了三个新方法Collections
类
Collections.emptyIterator
Collections.emptyEnumeration
Collections.emptyListIterator