首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >HashMap keySet变化未反映在地图中

HashMap keySet变化未反映在地图中
EN

Stack Overflow用户
提问于 2012-07-05 15:25:47
回答 5查看 4.2K关注 0票数 2

我试图在HashMap上迭代并将一些元素重写到另一个映射中,但我有以下问题:

代码语言:javascript
复制
@Test
public void test() {
    Map<SubClass, String> map = new HashMap<SubClass,String>();
    Map<SubClass, String> anotherMap = new HashMap<SubClass,String>();
    map.put(new SubClass(), "10");

    for(SubClass i : map.keySet()) {
        System.out.println(i); // initial (because toString is implemented)
        System.out.println(map.get(i)); // 10
        // here it's ok...

        i.name="another";

        System.out.println(i); // another
        System.out.println(map.get(i)); // null!
        // but here it occurs that  map.get(i) returns null!

        anotherMap.put(i, map.get(i));
    }
    for(SubClass i : anotherMap.keySet()) {
        System.out.println(i); // another
        System.out.println(map.get(i)); // null!
    }
}
// SubClass has String name; and hashCode and equals implemented

根据javadoc:

java.util.Map.keySet() 返回此映射中包含的键的集合视图。集合由映射支持,因此对映射的更改反映在集合中,反之亦然。如果映射是在集合上的迭代正在进行时被修改的(除非通过迭代器自己的移除操作),则迭代的结果是未定义的。集合支持元素删除,它通过Iterator.remove、Set.remove、removeAll、retainAll和clear操作从映射中删除对应的映射。它不支持add或addAll操作。

它说“地图的变化反映在集合中,反之亦然”。那么,为什么它的行为是这样的,也是最重要的:如何克服它,使两个映射只包含修改后的键和非空值?

更新:我的朋友在java1.5.0.19上做了这个测试(我有1.7.0_03,在1.5.0_21上也是这样),得到了正确的输出:

代码语言:javascript
复制
initial
10
another
10

UPDATE2:哦,他没有实现hashCode/相等,所以第一次更新是不相关的

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-07-05 15:32:38

你在修改钥匙而不是地图。Map<K,V>无法检测到您已经更改了其中的对象。要使映射“查看”调用remove(originalKey)所需的更改,请更改键,然后调用put(modifiedKey,object)

修改映射将是对clearputputAllremove的调用。

票数 5
EN

Stack Overflow用户

发布于 2012-07-05 18:19:41

根据java.util.Map javadoc

注意:如果将可变对象用作映射键,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是映射中的键,则不指定映射的行为。

换句话说,如果更改键对象的方式会影响映射中键的索引方式,则不需要映射正确工作。

票数 4
EN

Stack Overflow用户

发布于 2012-07-05 15:33:13

我相信i.name = "another"正在改变SubClass i对象的哈希代码,这就是为什么您要返回一个null值。如果hashcode函数Subclass不使用name,则代码将工作。

因此,当您调用anotherMap.put(i, map.get(i));时,您实际上是在调用anotherMap.put(i, null);

HashMap的目的是在O(1)时间内执行查找。这就是为什么它从SubClass i获取哈希代码而不更新它的原因。您的建议将需要一个懒惰的HashMap,但这将花费O(n)时间和目标。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11347541

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档