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

时间:2015-08-11 09:32:53

标签: java android list 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<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;
}

4 个答案:

答案 0 :(得分:6)

byte[](或任何数组)无法作为HashMap中的密钥正常工作,因为数组不会覆盖equals,因此两个数组将会只有当他们提到同一个对象时才被认为是平等的。

您必须将byte[]包装在覆盖hashCodeequals的某个自定义类中,并使用该自定义类作为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()方法。 我将以通用的方式包含答案,以便读者可以根据他们的要求获得想法并实施。

说,我有两个号码,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)将成立。

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

答案 3 :(得分:1)

您可以使用ByteBuffer,它是带有比较器的byte []数组的包装器。

从-https://stackoverflow.com/a/14087243/4019660

引荐答案