为何重写了equals()就必需要重写hashCode()

若是两个对象的equals判断为true,那么他俩的hashCode方法也必定相等。数组

重写equals()就必需要重写hashCode是针对HashSet 和Map 集合类型。结合框架只能存入对象(对象的引用(基本类型会自动装箱))。框架

一、在向hashSet中存入元素时,hashSet会调用该对象的hashCode()方法来获得该对象的hashCode()值,而后经过hashCode值决定该对象在hashSet中的存储位置。也就是说hashSet集合判断两个对象相等的标准是:两个对象经过equals()方法比较相等,而且对象的hashCode方法返回值也相等。若是两个元素经过equals()方法返回true,可是他们的hashCode方法返回的值不一样,hashSet也会把他们存储在不一样的位置,依然能够添加成功。spa

在向集合中插入对象时,集合中有不少元素,若是用equals方法的话效率就是一个很大的问题了。这个时候就使用HashCode方法,当集合要添加新的元素时,先调用HashCode方法,实际上在HashMap的实现中会用一个table来保存对象的HashCode值,若是table中没有这个值的话,就直接存进去,不用在进行任何比较了;若是存在该HashCode值,就调用他的equals方法与原先的元素进行比较,相同的话就替换原来的值,而且把原来的值返回,不相同就链表的形式往下存,这样一来调用equals方法的评率就大大下降了。对象

二、在Map集合中,好比说hashMap 存储的是<kety,value>对,key value都是对象,hashMap内部是经过key 对象的hashCode来计算桶的位置,这个桶里面可能存在多个对象(Entry对象,包含key对象和value对象),所以会利用key对象和桶里key对象调用equals逐一比较找到目标对象。当hashCode不一样会放到两个桶里(当hashMap 内部数组不能在扩容时,有可能计算的hash值相等,也就是在相同的桶,可是这种状况通常少见),所以当调用hashMap.get(key)时就不会找到你想要的目标对象。get

public class TestMap {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<String,String>();
        map.put("1","11");
        map.put("2","23");
        System.out.println(map.entrySet().toString());
        for (Entry<String, String> entity :  map.entrySet()){
            String value =  entity.getValue();
            String key = entity.getKey();
            System.out.println(key + ":" + value);
        }

    }
}

结果是:hash

[1=11, 2=23]
1:11
2:23it

在hashMap中利用高16位 ‘与’ 低16位来计算key的hash值的这样作主要是想散列的更散一些。尽可能让每位都参与到运算中来。table

 

总结一下下:若是equals方法获得的结果是false,则两个对象的HashCode值必定不相等;class

若是两个对象的HashCode值不相等,则equals方法获得的结果一定为false效率

若是两个对象的HashCode值相等,则equals方法获得的结果未知

相关文章
相关标签/搜索