只是判断两个对象的属性值是否相等
只需要一个类重写了equals,那么两个对象使用equals比较的时候比较的是属性值,但是不重写equals,比较的只是地址值。这时候hashcode值不相等。
如果同时重写了hashcode和equals,那么两个对象的hashcode值是相等的,同时两个对象比较也是比较属性值。
所以说,重写了hashcode,此类对象的hashcode值是相等的。重写了eqluas,进行比较的是属性值。如果单纯的比较值,重写equals即可。
HashMap和HashSet必须同时重写hashcode和equals
我们在使用set集合和map的时候由于不重复原则(不重复一般指对象的属性不相等),必须重写hashcoe和equals,是因为根据hash算法,会先比较hashcode值是否相等或者获取存储位置,然后再比较使用equals比较;如果不重写hashcode,那么hashcode指是不相等的,就会直接存储,不会进行equals比较,有可能造成属性相等,存储重复的对象,违背不重复原则,所以必须重写hashcode和equals。
HashMap(数组+链表)
Map底层是一个哈希表/散列表
–把数据存在桶里
–由数组 和 链表组成的
–当往HashMap里存放数据时,
会根据hash算法(hashCode())计算数据的存储位置(hash(key))
如果数组的位置没有数据,直接存在数组节点上.
如果数组的位置存过数据了(hash冲突),根据equals比较,相等,替换值,不相等,会形成链表结构.
jdk1.8对于链表结构的查询效率做了优化,当链表长度达到8时会变成红黑树来提升查询效率
所以说,Hashmap的key重写了hashcode和equals,会先根据hashcode找到数组位置,此位置没有数据,直接存储,如果此位置有数据,会根据equlas判断是否重复。如果不重写,hashcode值不相等,会直接存储,不会判断根据equlas判断,有时候key的值会重复,违背了map的key不能重复。
hashset(链表)
使用HashSet存储在链表中:
HashSet的add()方法,首先使用集合中的每一个元素和要添加的元素的hash值进行比较
如果hash值不一样,则直接添加元素
如果hash值一样,比较地址值或者使用equals方法进行比较
比较结果一样,则认为是重复不添加
所有的比较结果都不一样,则添加
所以说,hashset存储的时候会根据hashcode判断,如果不重写,hashcode不相等,会直接存储,如果重写了,hashcode相等,然后再回根据equals比较。