How will the Hashmap key behave if the hashcode is redefined so that it only returns a constant number?

I have a small question about Java Hashmap

. If I override the method hashCode

in such a way that:

@Override
public int hashCode(){
  return 9;
}

      

This will cause all keys Hashmap

to have the same index. Will they be placed in a linked list structure on the map, or will they only contain the last key that replaced all other keys?

+3


source to share


3 answers


They will be placed in the structure of linked lists in the map, assuming that you have not overridden the method equals

to always return true. Different keys can have the same hashcode, but if all keys have the same hashcode, your HashMap will become a linked list that defeats the purpose of using this structure in the first place.

You can see for yourself the implementation HashMap

:



/**
 * 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;
}

      

+4


source


The hashcode values ​​are used to reduce the search time for an object. The hashcode value is not necessarily unique across objects. In fact, the hashCode () method can be overridden so that it returns a constant integer for all objects (this, however, will lose the purpose of the hashCode () method). However, the default implementation of the Object class returns a unique integer for each object, since it maps the internal address of the object to an integer and returns it. But this is not a requirement.



+1


source


Whether it is referenced as related or not is debatable as it is not listed in the documentation. However, it will make sure to keep all items with unique keys (that is, the keys that are returned true

to the method equals

).

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 make the keys appear the same ... as expected because it hashCode

is only used to select the bucket to place the object.

0


source







All Articles