作者:感觉ly_382 | 来源:互联网 | 2023-08-19 18:05
当我使用Iterator
迭代 some 时TreeMap
,我发现相同Map.Entry
的内容会发生变化。例如:
import java.util.Map.Entry;
import java.util.TreeMap;
public class Solution {
public static void main(String[] args) {
TreeMap map = new TreeMap<>();
map.put(1,1);
map.put(2,2);
map.put(3,3);
System.out.println("map: " + map);
Map fromMap = map.tailMap(2);
System.out.println("fromMap: " + fromMap);
Iterator> iter = fromMap.entrySet().iterator();
Entry entry = iter.next();
System.out.println(entry); // line 1
iter.remove();
System.out.println(entry); // line 2. Why does entry content change?
}
}
结果:
map: {1=1, 2=2, 3=3}
fromMap: {2=2, 3=3}
2=2
3=3
该entry
在第1行和上述代码中的线2具有相同的参考,但是当我所说的内容改变iter.remove()
。
回答
从 Javadoc Map.Entry 中明确
如果在迭代器返回条目后修改了后备映射,则映射条目的行为是未定义的,除非通过对映射条目的 setValue 操作
从Map.Entry.getValue()
返回与此条目对应的值。如果映射已从支持映射中删除(通过迭代器的删除操作),则此调用的结果未定义
这意味着 Java 不保证如果您调用entry
afterremove
方法并且它未定义会发生什么 。
In other words, the implementation does not break the contract. But the behavior is really dangerous. I&#039;d have hoped to get immutable entries!
For reference, here&#039;s a comment of [Joshua Bloch on Twitter](https://twitter.com/joshbloch/status/1408718009833713669?s=21) on the reason why this choice had been made back in the days : `It seemed like a good idea at the time. Computers were 1000 times slower and had 1000 times less memory (roughly speaking).`