带有字节数组键和字符串值的哈希映射 - containsKey() 函数不起作用



我使用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[]在一些自定义类覆盖hashCodeequals,并使用该自定义类的关键到你的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()方法。我将以一种通用的方式给出答案,这样读者就可以了解我的想法,并根据自己的需求实现我的想法。

假设我有两个数字nr。我想要一个键值对,[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

最新更新