equals和hashCode概念

1、equals 比较的是对象的引用是否相等,即比较两个对象是否是同一个实例。

2、hashcode (哈希码)是一个整数值,它是根据对象的内容计算得出的。在Java中,哈希码主要用于散列数据结构,如哈希表。哈希表是一种常用的数据结构,它可以快速查找存储在其中的对象。哈希码可以帮助我们确定对象在哈希表中的存储位置,从而实现高效的查找操作。

重写equals和hashCode

1、未重写equals方法

默认情况下,Java中的 equals 方法比较的是对象的引用。如果我们不重写 equals 方法,那么对于两个不同的对象,即使它们的内容相同,调用 equals 方法也会返回 false,因为它们的引用不同。

public class Point {
    private final int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public static void main(String[] args) {
        Point p1 = new Point(1, 2);
        Point p2 = new Point(1, 2);
        System.out.println(p1.equals(p2));// false
    }
}

2、重写equals方法

class Point1 {
    private final int x, y;

    public Point1(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof Point1)) return false;
        Point1 point = (Point1) obj;
        return x == point.x && y == point.y;
    }

    public static void main(String[] args) {
        Point1 p1 = new Point1(1, 2);
        Point1 p2 = new Point1(1, 2);
        System.out.println(p1.equals(p2));// true

        Map<Point1, String> map = new HashMap<>();
        map.put(p1, "p1");
        System.out.println(map.get(p1)); // p1
        System.out.println(map.get(p2)); // null
    }
}

3、重写equals+hashcode方法

在Java中,哈希表使用哈希码来确定存储对象的位置。如果两个相等的对象具有不同的哈希码,那么它们将被存储在哈希表的不同位置,导致无法正确查找这些对象。

需要确保重写 equals 方法的对象也必须重写 hashCode 方法,以便它们的哈希码是相等的。这样,哈希表就能够正确地存储和查找这些对象了。

class Point2 {
    private final int x, y;

    public Point2(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof Point2)) return false;
        Point2 point = (Point2) obj;
        return x == point.x && y == point.y;
    }

    @Override
    public int hashCode() {
//		  方式一
//        int result = Integer.hashCode(x);
//        result = 31 * result + Integer.hashCode(y);
//        return result;

//		  方式二
//        Objects 类有一个静态方法,它接受任意数量的对象并为它们返回一个哈希码。
//        这个名为 hash 的方法可以 让你编写一行 hashCode 方法,其质量与根据这个项目中的上面编写的方法相当。
        return Objects.hash(x, y);
    }

    public static void main(String[] args) {
        Point2 p1 = new Point2(1, 2);
        Point2 p2 = new Point2(1, 2);
        System.out.println(p1.equals(p2));// true

        Map<Point2, String> map = new HashMap<>();
        map.put(p1, "p1");
//        map.put(p2, "p2");
        System.out.println(map.get(p1)); // p1
        System.out.println(map.get(p2)); // p1
    }
}