java - 删除后 TreeMap 迭代器行为不一致

标签 java

今天在尝试发现一个错误时,我发现 TreeMap 迭代器在删除对象时的行为有点奇怪。事实上,我在一个简单的例子中测试了不同的用途:

    TreeMap<String, String> map = new TreeMap<String, String>();
    map.put("1", "1");
    map.put("2", "2");
    map.put("3", "3");
    map.put("4", "4");
    map.put("5", "5");

    Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();

     while (iterator.hasNext()) {
        Map.Entry<String, String> entry = iterator.next();
        System.out.println("Before "+entry.getKey());
        iterator.remove();
        System.out.println("After " +entry.getKey());
    }

结果是:

Before 1
After 1 
Before 2
After 2
Before 3
After 3
Before 4
After 4
Before 5
After 5

但是如果我把它改成:

    TreeMap<String, String> map = new TreeMap<String, String>();
    map.put("1", "1");
    map.put("2", "2");
    map.put("3", "3");
    map.put("4", "4");
    map.put("5", "5");

    Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();

            String key = "4";

    while (iterator.hasNext()) {
        Map.Entry<String, String> entry = iterator.next();
        if(entry.getKey().equals(key)){
            iterator.remove();
            System.out.println(entry.getKey());
        }
    }

然后对于 key = 4,结果是 5,对于 key = 5,结果是 5,因为链接在删除时被更改。但是为什么行为不同。准时制?即使那是答案,他们不应该是统一的吗?

最佳答案

请参阅 Map.Entry 的 Javadoc对于 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.

一旦您删除了该条目,行为就不确定了,因此这可以解释为什么您会得到不同的结果。

注意:另一位用户 aix 发布了类似的答案,我打算对此发表评论,但由于某种原因已被删除/删除。

编辑:我不确定这个答案是否正确,因为我刚刚注意到 OP 正在调用 getKey() 而不是 getValue()

编辑 2:感谢 Ed Staub:我认为总体思路仍然成立,因为 Map.Entry 的 Javadoc 指出:

... more formally, 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.

关于java - 删除后 TreeMap 迭代器行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7488571/

相关文章:

java - 使用 FilterInputStream 删除 InputStream 的剩余部分

java - 如何使用 Hibernate 选择列?

java - RealmResults 查询返回部分结果 - Android

java - 为什么在这里省略泛型类型参数是可以接受的?

java - 日历日期不同

java - JPanel 和扩展 JPanel 的自定义类无法正确显示

java - 如何使用java检查文件夹的用户权限

java - IntelliJ 中更新代码并重建 Jar 文件不添加文件。我缺少什么?

java - 比较java中的两个字符串集并输出二进制(匹配/不)数组