我的计划是 公共课演示{
public static void main(String[] args) {
List<String> arr = new ArrayList<>();
arr.add("a");
arr.add("b");
Map<List<String>, String> map = new HashMap<>();
map.put(arr, "Ravinda");
System.out.println(map.get(arr));
arr.add("c");
System.out.println(map.get(arr));
}
}
输出是:拉文德拉和 空
我无法理解为什么第二个System.out.println的输出为空。
任何人都可以解释一下。
答案 0 :(得分:3)
当您致电:map.put(arr, "Ravinda");
时,您将“Ravinda”值的键设置为包含两个字符串的List。
通过调用arr.add("c");
,您正在修改先前使用的List来索引hashmap中的“Ravinda”值。
由于arr
列表已更改,因此它不再匹配您致电时指定的键:map.put(arr, "Ravinda");
这就是当您尝试第二次访问时,hashmap返回空值的原因。
hashmap仍包含'Ravinda'值,但此值是针对仅包含两个值的列表编制索引的。
答案 1 :(得分:2)
正如this answer所解释的那样,在使用散列码可变的对象时需要小心。 N
的{{1}}方法因其所包含的元素而异,因此通过将hashCode
添加到列表中,您已更改其哈希码。
重要的是要注意,即使哈希码没有改变,列表仍然必须相等。对象的哈希码不是唯一标识符,因此内部ArrayList
在检索其所在的存储桶后对密钥使用"c"
比较。
如果您有一个处于此位置的程序,则需要退后一步并确定解决问题的另一种方法。没有可靠的方法可以在Map中使用可变列表,但不会归结为引用相等(这使得事情无论如何都会毫无意义)。