equals方法和hashCode方法

2023-05-16

文章目录

  • 1、首先看看不重写情况下,equals方法和hashCode方法是干什么的
  • 2、为什么需要重写equals方法
  • 3、为什么要重写hashCode方法?
  • 4 总结
  • 5 快速生equals方法和hashCode方法

1、首先看看不重写情况下,equals方法和hashCode方法是干什么的

查看源码可以发现,equals()方法和hashCode()方法都是Objects类中的方法,其中equals()方法比较的是两个对象的地址是不是相同,hashCode()方法是根据地址值生成一个整数数值。

这就表明,在不重写情况下,两个new出来的对象,不管他们内部的值是否相同,地址一般来说是不同的,所以equals和hashCode方法得到的结果是不一样的。
在这里插入图片描述

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

2、为什么需要重写equals方法

这个其实是根据我们的实际需求来的,而不是必须重写。

上面讲过,原生的equals方法比较的是两个对象的地址是不是相等,也就是说,如果我们传入的是两个不同的对象,equals方法得到的结果大部分情况下是不相等的。

但是我们在代码中运用到equals()方法的场景是:我们有两个对象,想要比较两个对象的某些值,如果这些值相等,我们就认为这两个对象是相等的。显然这个目的,原生的equals不能满足,因此在这种需求的驱动下,我们需要重写equals方法。

举个例子,学生类,包含名字和年龄字段,如果名字和年龄都相等,我们就认为是同一个对象。

Student student01 = new Student("Tom", 25);
Student student02 = new Student("Tom", 25);

System.out.println(student01.equals(student02));

上述代码的结果是false,因为我们没有重写equals,比较的是两个对象的地址,自然是不相等的
在这里插入图片描述
现在我们重写equals方法:

class Student {
    public String name;
    public int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }
}

重写之后返回true
在这里插入图片描述

3、为什么要重写hashCode方法?

先讲一下hashCode方法会用在什么地方?

一般是在HashMap或者HashSet这种集合中会用到,当我们在这类集合中查找对象的时候,首先会根据传入的key和定义好的哈希函数得到一个哈希值,根据哈希值得到存放这个对象的数组的位置,再根据key的equals方法匹配相同key值获取对应的对象。

我们在写代码的时候,常常会通过HashSet或者HashMap给若干对象去重,这类集合在去重的时候会依次调用hashCode方法和equals方法,只有这两个函数返回的值都是相等的,这类集合才认为这两个对象重复了。

如果不重写hashCode方法,集合在去重的时候,会首先调用原生的hashCode方法,原生hashCode方法是根据两个对象的地址生成的哈希值,所以去重会失败。

举个例子,这里定义了两个Tom,目的是将重复的Tom去掉,这里是没有重写hashCode方法的,仅仅重写了equals方法。

public class Solution01 {
    public static void main(String[] args) {
        Student student01 = new Student("Tom", 25);
        Student student02 = new Student("Tom", 25);
        Student student03 = new Student("Jack", 23);

        Set<Student> studentSet = new HashSet<>();
        studentSet.add(student01);
        studentSet.add(student02);
        studentSet.add(student03);
        for (Student st : studentSet) {
            System.out.println(st.name + " " + st.age);
        }
    }
}

class Student {
    public String name;
    public int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }
}

结果显示,集合中仍然有3个对象。
在这里插入图片描述
现在我们重写hashCode方法

public class Solution01 {
    public static void main(String[] args) {
        Student student01 = new Student("Tom", 25);
        Student student02 = new Student("Tom", 25);
        Student student03 = new Student("Jack", 23);

        Set<Student> studentSet = new HashSet<>();
        studentSet.add(student01);
        studentSet.add(student02);
        studentSet.add(student03);
        for (Student st : studentSet) {
            System.out.println(st.name + " " + st.age);
        }
    }
}

class Student {
    public String name;
    public int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

得到的结果如下:
在这里插入图片描述

4 总结

重写equals方法是为了自定义判断两个对象是不是相等的标准,一般来说我们要求:两个对象的属性都相同就认为是相等的,原生的equals方法在判断两个对象是不是相等的标准是:两个对象的地址是不是相等。

重写hashCode方法的目的是为了实现将对象放入哈希集合中去重的目的。因为哈希集合是先通过hashCode方法,再通过equals方法来判断是不是重复。如果第一步hashCode都不等,就直接认为这两个对象不相等了。

重写equals方法必须重写hashCode方法其实是不准确的,需要根据需求来,如果你只想调用equals方法比较两个对象是不是相等,那就没有必要重写hashcode方法,但是更多的场景是将对象放入hashSethashMap中,而我们一般认为两个对象的属性都相等就等价于这两个对象就相等了。所以再这种情况下,重写了equals方法必须重写hashCode方法。

5 快速生equals方法和hashCode方法

idea,右键,如下:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

equals方法和hashCode方法 的相关文章

随机推荐