可以AnyOne请解释这个HashMap行为

时间:2018-06-10 04:09:55

标签: java collections

我的计划是 公共课演示{

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的输出为空。

任何人都可以解释一下。

2 个答案:

答案 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中使用可变列表,但不会归结为引用相等(这使得事情无论如何都会毫无意义)。