我使用HashMap: byte[]键和字符串值。但我意识到,即使我使用
放置相同的对象(相同的字节数组和相同的字符串值)myList.put(TheSameByteArray, TheSameStringValue)
到HashMap中,表仍然插入一个具有不同HashMapEntry的新对象。函数containsKey()不能工作
有人能给我解释一下吗?我该如何解决这个问题?谢谢。(Android Java)
@Override public boolean containsKey(Object key) {
if (key == null) {
return entryForNullKey != null;
}
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
K eKey = e.key;
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
return true;
}
}
return false;
}
byte[]
(或任何数组)不能作为HashMap
中的键正常工作,因为数组不覆盖equals
,所以两个数组只有在引用相同对象时才被认为是相等的。
你必须包装你的byte[]
在一些自定义类覆盖hashCode
和equals
,并使用该自定义类的关键到你的HashMap
添加到Eran的明确答案中,由于byte[]或任何数组都不会覆盖hashcode和equals(它使用Object类的默认方法),因此您始终可以封装一个以byte[]作为构造函数参数的String Object。String不仅在Map中形成好的键,而且它们也是不可变的(基于Hash的Map中的操作更快)
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html字符串(byte [])
注意:这是一种非常简单的创建数组或字符串(HashMap中的键)的方式,无需重写equals()或hashCode()方法。我将以一种通用的方式给出答案,这样读者就可以了解我的想法,并根据自己的需求实现我的想法。
假设我有两个数字n
和r
。我想要一个键值对,[n,r]
为键,(n+r)
为值。
Map<List<Integer>, Integer> map = new HashMap<List<Integer>, Integer>();
List<Integer> key = Arrays.asList(n, r);
if( map.containsKey(key) )
return map.get(key);
如果映射不包含键呢?
map.put(Collections.unmodifiableList(Arrays.asList(n, r)), (n+r));
unmodifiable
部分(没有进一步深入),确保密钥不能更改哈希码。
现在,map.containsKey(key)
将为真。
注意:这不是一个好方法。
您可以使用ByteBuffer
,它是带有比较器的byte[]数组的包装器。
参考答案- https://stackoverflow.com/a/14087243/4019660