为什么在 Java TreeMap 中调用 iterator.remove() 时相同的 Map.Entry 会发生变化?

Why does the same Map.Entry change when calling iterator.remove() in Java TreeMap?

当我用Iterator迭代一些TreeMap的时候,我发现同样的Map.Entry的内容会发生变化。例如:

import java.util.Map.Entry;
import java.util.TreeMap;

public class Solution {
    public static void main(String[] args) {
        TreeMap<Integer, Integer> map = new TreeMap<>();
        map.put(1,1);
        map.put(2,2);
        map.put(3,3);
        System.out.println("map: " + map);
        Map<Integer, Integer> fromMap = map.tailMap(2);
        System.out.println("fromMap: " + fromMap);
        Iterator<Entry<Integer, Integer>> iter = fromMap.entrySet().iterator();
        Entry<Integer, Integer> 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

上面代码第1行和第2行的entry有相同的引用,但是当我调用iter.remove()时内容发生了变化。

要从 Javadoc Map.Entry

中明确

The behavior of a map entry is undefined if the backing map has been modified after the entry was returned by the iterator, except through the setValue operation on the map entry

Map.Entry.getValue()

Returns the value corresponding to this entry. If the mapping has been removed from the backing map (by the iterator's remove operation), the results of this call are undefined

这意味着 Java 不能保证如果你在 remove 方法之后调用 entry 并且它是未定义的会发生什么。