浅谈HashMap以及重写hashCode()和equals()方法

HashMap和Hashtable的底层实现都是数组+链表结构实现的

使用HashMap,若是key是自定义的类,就必须重写hashcode()和equals()。

若是你重载了equals,好比说是基于对象的内容实现的,而保留hashCode的实现不变,那么极可能某两个对象明明是“相等”,而hashCode却不同。
这样,当你用其中的一个做为键保存到hashMap、hasoTable或hashSet中,再以“相等的”找另外一个做为键值去查找他们的时候,则根本找不到。
对于每个对象,经过其hashCode()方法可为其生成一个整形值(散列码),该整型值被处理后,将会做为数组下标,存放该对象所对应的Entry(存放该对象及其对应值)。 
equals()方法则是在HashMap中插入值或查询时会使用到。当HashMap中插入值或查询值对应的散列码与数组中的散列码相等时,则会经过equals方法比较key值是否相等,
因此想以自建对象做为HashMap的key,必须重写该对象继承object的hashCode和equals方法。
的源码的关键部分put
        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))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        modCount++;
        addEntry(hash, key, value, i);
        return null;

还有一点,位置0上存放的必定是null数组

而后在遍历这个位置上的链表的过程当中,若是发如今已经存在由equal函数肯定的相等的Key,那么用新的Value替换掉老的Value,并返回老的Value。否则就在链表最后添加结点,并返回null。函数

 

看一下get的源码this

    public V get(Object key) {
        if (key == null)
            return getForNullKey();
        Entry<K,V> entry = getEntry(key);

        return null == entry ? null : entry.getValue();
    }

再看getEntry的源码spa

  final Entry<K,V> getEntry(Object key) {
        if (size == 0) {
            return null;
        }

        int hash = (key == null) ? 0 : hash(key);
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }

意思很明确,就是先用hash函数肯定在哪一个位置,而后遍历这个位置上对应的链表,直到找到这个Key,而后返回value
这里有个地方很关键,那就是如何判判断相等咱们看到这里是靠equal函数来判断的,equal函数是全部类都会从Object类处继承的函数,code

当咱们在HashMap中存储咱们本身定义的类的时候,默认的equal函数的行为可能不能符合咱们的要求,因此须要重写。对象

总结:blog

一、若是两个对象相同(即用equals比较返回true),那么它们的hashCode值必定要相同;
二、若是两个对象的hashCode相同,它们并不必定相同(即用equals比较返回false)   继承

相关文章
相关标签/搜索