????????因为当我们把对象存入到底层为散列表结构的集合时,首先判断hashCode值,碰到相同的hashCode值之后再进行equals()进一步判断,这样保证如果两个对象是相等的,它们的equals()方法应该返回true,hashCode()也应该返回相同的结果。
????????遵守hashCode方法的常规约定。因为不能百分百确定这个类之后是否会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中用到,所以说重写equals()方法之后要尽量重写hashCode()方法。
注:hashCode方法的常规约定:
????????在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
????????如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
????????以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
????????实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
????????当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
下面案例展示在hashSet中添加相同的元素时只重写equals()的情况:
package com.xiaoyuan.object;
import java.util.HashSet;
import java.util.Set;
/**
* Copyright: Copyright (c) 2022/3/29 Asiainfo-Linkage
*
* @Description: Equals()方法的测试类
* @ClassName: EqualsTest
* @version: v1.0.0
* @author: wenronghui
* @date: 2022/3/29 16:05
* <p>
* Modification History:
* Date Author Version Description
* ---------------------------------------------------------*
* 2022/3/29 wenronghui v1.0.0 修改原因
*/
public class EqualsTest {
private int a1;
private int a2;
static class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public EqualsTest(int a1, int a2) {
this.a1 = a1;
this.a2 = a2;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
EqualsTest data = (EqualsTest) obj;
return a1 == data.a1 && a2 == data.a2;
}
@Override
public String toString() {
return "EqualsTest{" +
"a1=" + a1 +
", a2=" + a2 +
'}';
}
// 重写的hashCode方法
// @Override
// public int hashCode() {
// return Objects.hash(a1,a2);
// }
/**
* @Function: EqualsTest.java
* @Description: 底层为散列表结构的集合存放数据只重写了equals()的情况
*
* @param:参数描述
* @return:返回结果描述 将三个对象存入到HashSet集合中,根据set中不能存放重复元素的原理,
* 遍历集合得到的结果应该是只有两个。因为虽然p1 和 p2的内容相等,但是它们的hashCode()不等;
* 所以,HashSet在添加p1和p2的时候,认为它们不相等。
* @throws:异常描述
*
* @version: v1.0.0
* @author: wenronghui
* @date: 2022/3/30 10:58
*
* Modification History:
* Date Author Version Description
*---------------------------------------------------------*
* 2022/3/30 wenronghui v1.0.0 修改原因
*/
public static void main(String[] args) {
EqualsTest data1 = new EqualsTest(1,2);
EqualsTest data2 = new EqualsTest(1,2);
EqualsTest data3 = new EqualsTest(2,4);
Set<EqualsTest> set = new HashSet<>();
set.add(data1);
set.add(data2);
set.add(data3);
for (EqualsTest data : set){
System.out.println(data);
}
}
}
输出结果:
?我们看到重复的元素被存放到了hashSet中,这对于不能有重复元素的Set集合是很大的错误,因此我们需要重写hashCode方法来保证底层是散列表结构的数据结构的不可重复的特征,下面是重写了hashCode()方法之后:
?可以避免散列表结构存储了相同元素的冲突。
|