How will Hashmap key behave if hash code is overridden such that it returns only a constant number?

前端 未结 3 1069
一向
一向 2021-01-19 05:49

I have a small question about Java Hashmap. If I override the hashCode method such that:

@Override
public int hashCode(){
  return          


        
相关标签:
3条回答
  • 2021-01-19 06:20

    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.

    0 讨论(0)
  • 2021-01-19 06:25

    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;
    }
    
    0 讨论(0)
  • 2021-01-19 06:28

    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

    0 讨论(0)
提交回复
热议问题