How to make HashMap work with Arrays as key?
Map
implementations relies on key's equals
and hashCode
methods. Arrays in java are directly extends from Object
, they use default equals
and hashCode
of Object
which only compares identity
.
If I were you, I would create a class Key
class Key {
private final boolean flag1;
private final boolean flag2;
public Key(boolean flag1, boolean flag2) {
this.flag1 = flag1;
this.flag2 = flag2;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof Key)) {
return false;
}
Key otherKey = (Key) object;
return this.flag1 == otherKey.flag1 && this.flag2 == otherKey.flag2;
}
@Override
public int hashCode() {
int result = 17; // any prime number
result = 31 * result + Boolean.valueOf(this.flag1).hashCode();
result = 31 * result + Boolean.valueOf(this.flag2).hashCode();
return result;
}
}
After that, you can use your key with Map
:
Map<Key, Integer> map = new HashMap<>();
Key firstKey = new Key(false, false);
map.put(firstKey, 1);
Key secondKey = new Key(false, false) // same key, different instance
int result = map.get(secondKey); // --> result will be 1
Reference: Java hash code from one field
It is not possible to do this with arrays, as any two different arrays don't compare equals
, even if they have the same elements.
You need to map from container class, for example ArrayList<Boolean>
(or simply List<Boolean>
. Perhaps BitSet
would be even more appropriate.
You cannot do it this way. Both t
and a
will have different hashCode()
values because the the java.lang.Array.hashCode()
method is inherited from Object
, which uses the reference to compute the hash-code (default implementation). Hence the hash code for arrays is reference-dependent, which means that you will get a different hash-code value for t
and a
. Furthermore, equals
will not work for the two arrays because that is also based on the reference.
The only way you can do this is to create a custom class that keeps the boolean
array as an internal member. Then you need to override equals
and hashCode
in such a way that ensures that instances that contain arrays with identical values are equal and also have the same hash-code.
An easier option might be to use List<Boolean>
as the key. Per the documentation the hashCode()
implementation for List
is defined as:
int hashCode = 1;
Iterator<E> i = list.iterator();
while (i.hasNext()) {
E obj = i.next();
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
As you can see, it depends on the values inside your list and not the reference, and so this should work for you.