欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

equals()方法和hashCode()的使用

程序员文章站 2024-03-26 09:19:17
...

1. 原生equals()方法的内容:
public boolean equals(Object obj) {
    return (this == obj);
}

  equals方法在其内部是调用了"==",所以说在不重写equals方法的情况下,equals方法是比较两个对象是否具有相同的引用,即是否指向了同一个内存地址。

而在业务系统中,有时候需要的并不是一种严格意义上的相等,而是业务上的对象相等。比如:如果两个对象中的id相等,那么就认为这两个对象是相等的。

2.重写equals()方法,需要遵守的通用约定

   1>自反性
       对于任意非null的引用值x,x.equals(x)必须返回true。
   2>对称性
      对于任意非null的引用值x、y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。
   3>一致性
      对于任意非null的引用值x、y,只要equals方法的比较操作在对象中所用的信息没有发生改变,那么多次调用x.equals(y)应该        一致的返回true或false。
   4>传递性
      对于任意非null的引用值x、y、z,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)必须返回true。
      对于任意非null的引用值x,x.equals(null)必须返回false。

   5> 非空性

      对于任意null的引用值x,x.equals(null) 一定是false。

3.hashCode()

   原生写法:

public native int hashCode();

hashCode是一个本地方法,他返回的是这个对象的内存地址。   

这个方法返回对象的散列码,返回值是int类型的散列码。
   对象的散列码是为了更好的支持基于哈希机制的Java集合类,例如 Hashtable, HashMap, HashSet 等。

   重写hashCode方法时除了上述一致性约定,还有以下几点需要注意:

 (1)返回的hash值是int型的,防止溢出。

 (2)不同的对象返回的hash值应该尽量不同。(为了hashMap等集合的效率问题)

 (3)《Java编程思想》中提到一种情况

“设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。如果在讲一个对象用put()添加进HashMap时产生一个hashCdoe值,而用get()取出时却产生了另一个hashCode值,那么就无法获取该对象了。所以如果你的hashCode方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化时,hashCode()方法就会生成一个不同的散列码”。

4. 重写equals()方法必须重写hashCode()方法

    原因:hashCode()方法在Object规范中的通用约定第二条,相等的对象必须具有相等的散列码。

    1>在应用运行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么多次调用该对象的equals方法应该始终如一的返回同一个整数。在同一个应用程序的多次执行过程中,每次执行equals方法所返回的整数可以不一致。
    2>如果两个对象使用equals(Object)方法比较是相等的,那么调用这两个对象中的任意一个对象的hashCode方法都必须产生相同的一个整数结果。
    3>如果两个对象使用equals(Object)方法比较是不相等的,那么调用这两个对象中的任意一个对象的hashCode方法,则不一定要产生不同的整数结果。如果给不同的对象产生不同的hash码,有可能提高散列表性能(比如往HashMap中添加数据时,具体添加到哪个桶中,就是根据(table.length - 1) & hash来计算的)。

如果一个类重写了equals方法但是没有重写hashCode方法,那么该类无法结合所有基于散列的集合(HashMap,HashSet)一起正常运作。

5.写法

equals()方法和hashCode()的使用

31*N可以被编译器优化为左移5位后减1即31*N =(N<<5)-1,有较高的性能。使用31的原因可能是为了更好的分配hash地址,并且31只占用5bits! 所以从效率上 它是2的5次减1,对计算机来说2的乘除操作只需要做位移操作,例如*32就是左移5位。 也就是说31对计算机的角度来说运算更快、切占内存不多不少,而且形成惯例,虚拟机甚至都专门对他做了优化。所以常用31做系数算hashcode 

 

相关标签: equals hashCode