Java中hashCode 和 equals 的处理

文章目录

  • Java中hashCode 和 equals 的处理
  • 1. 阿里巴巴编程规范要求
  • 2. equals和hashcode的分析
    • 2.1 Object方法
    • 2.2 只覆写(Override)equals带来的问题
      • 问题演示
      • 问题分析
      • 问题处理

Java中hashCode 和 equals 的处理

1. 阿里巴巴编程规范要求

Java中hashCode 和 equals 的处理_第1张图片

2. equals和hashcode的分析

2.1 Object方法

java中,所有类都直接或间接继承自java.lang.Object类,也就是Object是java中所有类的祖先即根类

equals和hashcode是Object类提供的方法:
Java中hashCode 和 equals 的处理_第2张图片

  • 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

你可能感兴趣的:(java,java)