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

2022-09-02 03:59:51

当我用来迭代一些时,我发现相同的内容会改变。例如:IteratorTreeMapMap.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 行具有相同的引用,但是当我调用 时内容会发生变化。entryiter.remove()


答案 1

从Javadoc Map.Entry中可以清楚地看出

如果在迭代器返回后支持映射已被修改,则映射条目的行为未定义,除非通过映射条目上的 setValue 操作

来自 Map.Entry.getValue()

返回与此条目对应的值。如果映射已从后备映射中删除(通过迭代器的 remove 操作),则此调用的结果未定义

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


答案 2