首先,重写这两个方法,主要是用于保持hashmap与hashset的去重特性的。
1.为什么重写hashcode()方法
(1)hashmap进行put方法时,首先对key对象进行hash操作,其中就包含了hashcode()方法 的调用。通过hashcode()方法得到key的hash值,然后对hash值进行取模运算得到了在hashmap存储中的下标索引值。(详情可以自己查看源码)
(2)如果不重写hashcode()方法,则即使相同内容的对象object1和object2,因为没有重写hashcode()方法,因为使用其引用地址作为输入计算得到的hash值也不一样,从而在hashmap中的索引值也不一样。
(3)在进行put操作时,由于索引不同,两个内容相同的对象被put进入不同的桶锁对应的链表中。
这样,hashmap中就存在了两个内容相同的对象,违背了hashmap的不含重复元素的特性。
因此,为了保证相同内容的对象,应该被put进入同一个桶所对应的链表,需要重写hashcode方法。
重写hashcode方法后,计算hash值使用的对象的内容进行hash运算。可以保证两个内容相同的对象 ,计算得到的hash值相同,从而进一步计算得到的下标索引值相同,可以保证了两个内容相同的对象可以put进入同一个桶中。
2.为什么重写equals()方法
(1)当我们重写了hashcode方法之后,保证了两个内容相同的对象可以放到同一个桶中。
(2)但是,当进行put方法的时候,找到指定下标索引后,还需要进行比较操作,如果该对象已经存在于链表中,则用新的value值将其覆盖;如果不存在,则插入到链表中;
(3)而比较两个对象是否相同,使用的是equals()方法。
(4)假设我们没有重写equals方法,在put第二个内容相同的对象时,由于Object类的原生equals方法默认比较的是两个对象的引用地址,因此两个内容相同的对象,其equals方法返回值为false,则会认为插入的第二个对象在链表中不存在,而将第二个对象插入到链表,不会覆盖第一个对象;
这样,还是违背了hashmap的不含重复元素的特性。
因此,为了保证相同内容的对象,应该在hashmap中只存在一个,需要重写equals方法。
(5)重写equals方法使其比较两个对象的内容是否相同,此时再次进行put操作,由于object2和object1的内容相同,equals方法返回true,则会使用object2对象覆盖掉object1,保证了hashmap中只包含了一个内容相同的对象;
保证了hashmap不包含重复元素的这一特性。
hashset同理。