文章目录
- hashCode 和 equals 的处理
- 1. 阿里巴巴编程规范要求
- 2. equals和hashcode的分析
- 2.1 Object方法
- 2.2 只覆写(Override)equals带来的问题
- 问题演示
- 问题分析
- 问题处理
hashCode 和 equals 的处理
1. 阿里巴巴编程规范要求
2. equals和hashcode的分析
2.1 Object方法
java中,所有类都直接或间接继承自java.lang.Object类,也就是Object是java中所有类的祖先即根类
equals和hashcode是Object类提供的方法:
- hashcode方法:返回的是一个对象的hash码,是由Object类本地方法生成的
- equals方法:比较的对象的引用地址
在Java的一些集合类中,一般会重写这两个方法。 在比较两个对象是否相等时候,会根据以下规则,会先调用对象的hashCode方法得到hashCode进行比较,如果hashCode不相同,就可以直接认为这两个对象不相同,如果hashCode相同,那么就会进一步调用equals方法进行比较,而equals方法,就是用来最终确认两个对象是否相等的。
通常equals方法比较重,逻辑比较多,而hashCode方法主要就是得到一个哈希值,实际上是一个数字,相对而言比较轻,所以比较两个对象时,通常会先根据hashCode比较一下
2.2 只覆写(Override)equals带来的问题
如果只覆写(equals)而不复写hashcode,可能导致导致equals相等,而hashcode不相等,在使用HashMap进行存储时候会出现问题
问题演示
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
public class TestHashMap {
public static void main(String[] args) {
Map<Person, String> map = new HashMap<>();
map.put(new Person("Kevin"),"Hi");
System.out.println(map.get(new Person("Kevin")));
}
}
执行结果:
null
问题分析
因为散列结合是使用 hashCode 来计算 key 的存储位置,如果存储两个完全相同的对象,但是有不同的 hashcode 就会导致这两个对象存储在 hash 表的不同位置,当我们想根据这个对象去获取数据的时候,就会出现一个完全相同的对象会在存储在 hash 表的两个位置。
问题处理
重写hashCode方法
重新equals方法一定要重写hashCode方法
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
再次执行结果:
Hi