当Arraylist增长时,带有ArrayList键的HashMap无法找到它

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当Arraylist增长时,带有ArrayList键的HashMap无法找到它相关的知识,希望对你有一定的参考价值。

我的问题是,在我的代码的某些部分,我使用arraylist作为hashmap中的键

ArrayList<Integer> array = new ArrayList<Integer>();

然后我将我的数组作为哈希映射中的一个键(我需要它以这种方式我确定)

HashMap<ArrayList<Integer>, String> map = new HashMap<ArrayList<Integer>, String>();
map.put(array, "value1");

问题出在这里:当我向我的数组添加一些值然后我尝试使用相同的数组恢复数据时,哈希映射无法找到它。

array.add(23);
String value = map.get(array);

此时值为null而不是字符串“value1”我正在测试,我发现当数组列表增长时hashCode会发生变化,这是我问题的中心点,但我想知道如何解决这个问题。

答案

使用IdentityHashMap。然后,无论其内容(以及哈希代码)如何更改,相同的数组实例将始终映射到相同的值。

另一答案

您不能使用可变对象(即hashCode更改的对象)作为HashMap的关键字。看看你是否能找到其他东西作为钥匙。将集合映射到字符串有点不寻常;另一种方式更常见。

另一答案

它是一个奇怪的用例但如果你必须这样做,那么你可以对数组进行子类化并覆盖hashCode方法。

另一答案

在我看来,尝试做的事情有点添加。

我假设你要模拟的是一个由n个整数组成的可变长度键,并假设ArrayList的哈希值是一致的,但我不确定是这种情况。

我建议你要么继承ArrayList并覆盖hash()equals()方法,要么将HashMap包装在一个关键类中。

另一答案

我几乎肯定你不想那样做。你更有可能想要一个Map<String, List<Integer>>。但是,如果您绝对必须这样做,请使用持有者类:

public class ListHolder {
    private List<Integer> list = new ArrayList<Integer>();
    public List<Integer> getList() {return list;}
}

Map<ListHolder, String> map = new HashMap<ListHolder, String>;
另一答案

基本原因:当我们使用HashMap.put(k,v)时,它将数字k.hashCode(),以便它可以知道放在哪里。

它还可以通过这个数字找到值(k.hashCode());

您可以看到ArrayList.hashCode()函数,它位于AbstractList的抽象类中。显然,在我们添加一些对象之后,它会改变haseCode值。所以我们找不到值使用HashMap.get(K)并且没有hashCode为K的元素。

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

以上是关于当Arraylist增长时,带有ArrayList键的HashMap无法找到它的主要内容,如果未能解决你的问题,请参考以下文章

JavaSE--简答题5

ArrayList增删改方法实现

集合 ArrayList 增删改除

当数据增长时,带有分页的 Cassandra 查询第二个索引变得更慢

简易版Java ArrayList(增删改查)

Java的动态数组:ArrayList的简单运用(增删改查)