当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无法找到它的主要内容,如果未能解决你的问题,请参考以下文章