我使用HashMap:byte []键和String值。但我意识到即使我使用
放置相同的对象(相同的字节数组和相同的字符串值)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;
}
答案 0 :(得分:6)
byte[]
(或任何数组)无法作为HashMap
中的密钥正常工作,因为数组不会覆盖equals
,因此两个数组将会只有当他们提到同一个对象时才被认为是平等的。
您必须将byte[]
包装在覆盖hashCode
和equals
的某个自定义类中,并使用该自定义类作为HashMap的键。
答案 1 :(得分:1)
添加到Eran的明确答案,因为byte []或任何数组都不会覆盖hashcode和equals(它使用Object类的默认方法),所以你总是可以使用byte []作为构造函数参数来包装一个String对象。只有String在Map中形成好的键,它们也是不可变的(基于Hash的映射中的操作更快)
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String(byte[])
答案 2 :(得分:1)
注意:这是制作数组或字符串(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)
将成立。
注意:这不是一个好方法。这只是一种解决方法。
答案 3 :(得分:1)
您可以使用ByteBuffer
,它是带有比较器的byte []数组的包装器。