在我的程序中,我有一个HashMap。它将字符串的HashSets作为其键,将字符串的PriorityQueues作为其值。当我更改其中一个键的内容时,它不再保留为HashMap的成员。这对我来说似乎很奇怪,因为我没有更改密钥的引用。我只是改变了它的内容。请查看以下代码段:
HashMap<HashSet<String>, PriorityQueue<String>> myHashMap=new HashMap<>();
HashSet<String> myHashSet=new HashSet<>();
myHashSet.add("abc");
myHashSet.add("mnq");
myHashSet.add("al;ksghl");
PriorityQueue<String> myPriorityQueue=new PriorityQueue<>();
myPriorityQueue.add("3h4");
myPriorityQueue.add("lskdjf");
myHashMap.put(myHashSet, myPriorityQueue);
if(myHashMap.containsKey(myHashSet))
System.out.println("Yes!");
myHashSet.remove("abc");
if(myHashMap.containsKey(myHashSet))
System.out.println("Yes!");
基本上,我希望看到两个“是的!”,实际上,它只打印一个。我做了一个彻底的调试,并意识到myHashSet的参考号在删除其中一个成员后没有改变。所以,这个程序没有理由不打印第二个“是的!”。
非常感谢任何形式的帮助。
答案 0 :(得分:6)
更改集的内容会更改其标识和哈希码。由于地图使用equals
和hashCode
来查找并比较其键,因此会破坏地图的完整性,而不会再找到该地图中显示的内容。
引用the Javadoc:
注意:如果将可变对象用作映射键,则必须非常小心。如果在对象是地图中的关键字时,以影响
equals
比较的方式更改对象的值,则不会指定地图的行为。
尝试添加行
System.out.println(myHashSet.hashCode());
在remove
来电之前和之后看到差异。
答案 1 :(得分:1)
关键字的哈希/等于的Hashmap键(已经指出,正在改变)。如果您关心身份,则应使用java.util.IdentityHashMap