equals方法
Object
类中的 equals()
方法定义如下
public boolean equals(Object obj) {
return (this == obj);
}
==的作用
-
基本数据类型:比较的是
==
两边值是否相等 -
引用数据类型:比较的是
==
两边内存地址是否相等
基本数据类型包括: byte
, short
, char
, int
, long
, float
, double
, boolean
hashCode方法
Object
中的 hashCode()
方法是一个本地方法,返回一个 int
类型的哈希值。
public native int hashCode();
-
如果对象在使用
equals
方法中进行比较的参数没有修改,那么多次调用一个对象的hashCode()
方法返回的哈希值应该是相同的。 -
如果两个对象通过
equals
方法比较是相等的,那么要求这两个对象的hashCode
方法返回的值也应该是相等的。 -
如果两个对象通过
equals
方法比较是不同的,那么也不要求这两个对象的hashCode
方法返回的值是相同的。但是我们应该知道对于不同对象产生不同的哈希值对于哈希表(HashMap等等)能够提高性能。
为什么重写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不包含重复元素的这一特性。