具有字节数组键和字符串值的 HashMap - containsKey() 函数不起作用

HashMap with byte array key and String value - containsKey() function doesn't work

我正在使用 HashMap:byte[] 键和字符串值。但我意识到即使我使用

放置相同的对象(相同的字节数组和相同的字符串值)
myList.put(TheSameByteArray, TheSameStringValue)

到HashMap中,table仍然插入一个新的对象,具有不同的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;
}

A byte[](或任何数组)无法作为 HashMap 中的键正常工作,因为数组不会覆盖 equals,因此将考虑两个数组仅当它们引用同一对象时才相等。

您必须将 byte[] 包装在一些覆盖 hashCodeequals 的自定义 class 中,并将该自定义 class 用作你的 HashMap 的关键。

添加到 Eran 的明确答案中,因为 byte[] 或任何数组都不会覆盖 hashcode 和 equals(它使用 Object class 的默认方法),你总是可以环绕一个字符串对象,它需要 byte[ ] 作为构造函数 argument.Not String 只在 Map 中形成好的键,它们也是不可变的(基于 Hash 的 map 中的操作更快)

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String(byte[])

注意:这是一种在不重写 equals() 或 hashCode() 方法的情况下生成数组或字符串(HashMap 中的键)的极其 hack-y 的方法。 我将以通用的方式包含答案,以便读者可以根据他们的要求了解并实施。

比如说,我有两个号码,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[] 数组的包装器。

参考答案来自 -