I'm using a HashMap: byte[] key and String value. But I realize that even I put the same object (same byte array and same string value) by using
myList.put(TheSameByteArray, TheSameStringValue)
into HashMap, the table still inserts a new object with different HashMapEntry. Then function containsKey() cannot work.
Can someone explains this for me? How can I fix this? Thanks. (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;
}
NOTE: This is an extremely hack-y way of making an array or a string, a key in a HashMap, without overriding either the equals() or the hashCode() methods. I'll include the answer in a generic way, so readers can get the idea and implement as per their requirements.
Say, I have two numbers,
n
andr
. I want a key-value pair with[n,r]
as the key, and(n+r)
as the value.What if the map did not contain the key?
The
unmodifiable
part (without going into any further depth), ensures that the key cannot change the hash code.Now,
map.containsKey(key)
will be true.Note: This is not a good way to do it. It is just a workaround.
A
byte[]
(or any array) can't work properly as a key in aHashMap
, since arrays don't overrideequals
, so two arrays will be considered equal only if they refer to the same object.You'll have to wrap your
byte[]
in some custom class that overrideshashCode
andequals
, and use that custom class as the key to your HashMap.Adding to Eran's clear answer,Since byte[] or any array doesnt override hashcode and equals(it uses the default methods of Object class ),you can always wrap around a String Object which takes byte[] as constructor argument.Not only does String form good keys in Map,they are immutable too(the operations in a Hash based map are faster)
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String(byte[])