带字节数组键和字符串值的HashMap – containsKey()函数不起作用

我正在使用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[] tab = table; for (HashMapEntry 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 ,因此只有当两个数组引用同一个对象时才会认为它们是相等的。

你必须在一些覆盖hashCodeequals自定义类中包装你的byte[] ,并使用该自定义类作为HashMap的键。

添加到Eran的明确答案,因为byte []或任何数组都不会覆盖hashcode和equals(它使用Object类的默认方法),所以你总是可以使用byte []作为构造函数参数来包装一个String对象。不仅仅是String在Map中形成好的键,它们也是不可变的(基于Hash的映射中的操作更快)

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String(字节%5B%5D)

注意:这是制作数组或字符串(HashMap中的键)的一种非常黑客的方式,不会覆盖equals()或hashCode()方法。 我将以通用的方式包含答案,以便读者可以根据他们的要求获得想法并实施。

说,我有两个数字, nr 。 我想要一个键值对,其中[n,r]为键, (n+r)为值。

 Map, Integer> map = new HashMap, Integer>(); List 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)将为true。

注意:这不是一个好方法。 这只是一种解决方法。