I have a small question about Java Hashmap
. If I override the hashCode
method such that:
@Override
public int hashCode(){
return
Whether it appears as a linked list or not is debatable as it does not state in the documentation. However, it will certainly keep all items with unique keys (i.e. keys that return true
to the equals
method).
class Nine {
final String value;
public Nine(String value) {
this.value = value;
}
@Override
public int hashCode() {
return 9;
}
@Override
public boolean equals(Object it) {
return it instanceof Nine && ((Nine) it).value.equals(value);
}
@Override
public String toString() {
return value;
}
}
class AlwaysNine extends Nine {
public AlwaysNine(String value) {
super(value);
}
@Override
public boolean equals(Object it) {
return it instanceof Nine;
}
}
public void test() {
System.out.println("Hello");
Map<Nine, String> testMap = new HashMap<Nine, String>();
testMap.put(new Nine("Nine"), "Nine");
testMap.put(new Nine("nine"), "nine");
testMap.put(new AlwaysNine("nIne"), "nIne");
System.out.println(testMap);
}
prints
{Nine=nIne, nine=nine}
which proves that only overriding equals
will force keys to seem to be the same ... as expected because hashCode
is only used to pick the bucket in which to place the object.
They will be placed in a linked list structure in the map, assuming you didn't override the equals
method to always return true. Different keys may have the same hashCode, but if all the keys have the same hashCode, your HashMap would become a linked list, which defeats the purpose of using this structure in the first place.
You can see it for yourself in a HashMap
implementation :
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
* (A <tt>null</tt> return can also indicate that the map
* previously associated <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode()); // hash would always be the same if hashCode is constant
int i = indexFor(hash, table.length); // i would always be the same if hashCode is constant
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { // the key is searched using the
// equals method
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
Hashcode values are used to reduce the search time of an object . The hashcode value does not necessarily be unique for distinct objects. The hashCode() method may in fact, be overridden in such a way that it returns a constant integer for all objects (this would however defeat the purpose of hashCode() method). However, the default implementation of class Object does return a unique integer for every object, as it maps the internal address of the object to an integer and returns the same. But this is not a requirement