有人能解释一下这个HashMap的行为吗?

3

我的程序是

公共类Demo {

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));
}

输出结果为:Ravindra和null。

我不明白为什么第二个System.out.println的输出结果是null。

有人能解释一下吗?

2个回答

3
当您调用map.put(arr, "Ravinda");时,您设置了“Ravinda”值的键为包含两个字符串的List。
通过调用arr.add("c");,您修改了早期用于索引哈希映射中“Ravinda”值的List。
由于arr列表已更改,它不再与您调用map.put(arr, "Ravinda");时指定的键匹配。
这就是为什么第二次尝试访问哈希映射时,它返回null值的原因。
哈希映射仍然包含“Ravinda”值,但此值以仅包含两个值的列表为索引。

2
正如这个答案所解释的那样,当使用一个可变哈希码的对象时需要小心。对于一个ArrayList,其hashCode方法取决于它包含的元素,因此通过向列表添加"c",您已经改变了它的哈希码。
值得注意的是,即使哈希码没有改变,列表仍然必须相等。对象的哈希码不是唯一标识符,因此在检索到它所在的桶后,HashMap在键上使用equals比较。
如果您的程序处于这种情况下,您需要退一步并确定另一个解决问题的方法。没有可靠的方法可以在Map中使用可变列表而不会归结为引用相等(这也使事情变得非常无意义)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接