为什么在 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
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
并且它是未定义的会发生什么。
当我用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
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
并且它是未定义的会发生什么。