面试题-JAVA基础3-equals方法与==以及hashCode方法

94 阅读3分钟

1. equals方法

equals方法是Object的方法

image.png

public boolean equals(Object obj) {  
    return (this == obj);  
}

官网注释翻译:

判断其他对象是否“等于”此对象。

equals 方法在非 null 对象引用上实现等价关系:

  • 自反性:对于任何非 null 引用值 x,x.equals(x) 都应返回 true。
  • 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 应返回 true。
  • 可传递:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,y.equals(z) 返回 true,则 x.equals(z) 应返回 true。 一致性:对于任何非空引用值 x 和 y,x.equals(y) 的多次调用将始终返回 true 或始终返回 false,前提是未修改对象的等值比较中使用的信息。对于任何非 null 引用值 x,x.equals(null) 应返回 false。类 Object 的 equals 方法在对象上实现了最具区分性的等价关系;也就是说,对于任何非 null 引用值 x 和 y,当且仅当 x 和 y 引用同一对象时,此方法返回 true(x == y 的值为 true)。

请注意,每当 hashCode 方法被重写时,通常都需要重写此方法,以便维护 hashCode 方法的通用协定,该方法规定相等的对象必须具有相等的哈希代码。

Params: obj – 要与之比较的引用对象。返回:如果此对象与 obj 参数相同,则返回 true;否则为 false。参见:hashCode()、java.util.HashMap

引用地址:

image.png

地址查看

maven引入jol工具包

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

结论:

  1. 对于基本数据类型,==比较的是是否相等
  2. 对于引用类型,==比较对象地址是否相等
  3. equals方法是Object对象的方法,其作用和==相同,但是在String等对象中对该方法进行了重写,用来比较是否相等

hashCode

为什么重写equals方法后,hashCode方法也必须重写
hashCode方法返回对象的散列码,返回值是int类型的散列码。散列码的作用是确定该对象在哈希表中的索引位置。

关于hashCode有一些约定:

  • 两个对象相等,则hashCode一定相同。
  • 两个对象有相同的hashCode值,它们不一定相等。
  • hashCode()方法默认是对堆上的对象产生独特值,如果没有重写hashCode()方法,则该类的两个对象的hashCode值肯定不同
  1. 根据规定两个对象相等,hashCode值也许相同,所以重写equals方法后,hashCode方法也必须重写
  2. hashCode在具有哈希机制的集合中起着非常关键的作用,比如HashMapHashSet等。以HashSet为例,HashSet的特点是存储元素时无序且唯一,在向HashSet中添加对象时,首相会计算对象的HashCode值来确定对象的存储位置,如果该位置没有其他对象,直接将该对象添加到该位置;如果该存储位置有存储其他对象(新添加的对象和该存储位置的对象的HashCode值相同),调用equals方法判断两个对象是否相同,如果相同,则添加对象失败,如果不相同,则会将该对象重新散列到其他位置。所以重写equals方法后,hashCode方法不重写的话,会导致所有对象的HashCode值都不相同,都能添加成功,那么HashSet中会出现很多重复元素,HashMap也是同理(因为HashSet的底层就是通过HashMap实现的),会出现大量相同的Key(HashMap中的key是唯一的,但不同的key可以对应相同的value)。所以重写equals方法后,hashCode方法也必须重写。同时因为两个对象的hashCode值不同,则它们一定不相等,所以先计算对象的hashCode值可以在一定程度上判断两个对象是否相等,提高了集合的效率。
  3. 总结一下,一共两点:第一,在HashSet等集合中,不重写hashCode方法会导致其功能出现问题;第二,可以提高集合效率。