Java 重写equals的时候为什么一定要重写hashcode-一个例子

Posted

Catch Spark. Code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 重写equals的时候为什么一定要重写hashcode-一个例子相关的知识,希望对你有一定的参考价值。

实体类

class Point {
    private int x;
    private int y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)//ref相等
        {
            return true;
        }
        if (obj == null || this.getClass() != obj.getClass()) {
            return false;
        }
        Point that = (Point) obj;
        return x == that.x && y == that.y;//对比值
    }
}

以上代码重写了equals。

比较

@Slf4j
public class EqualsHashDemo {


    public static void compare() {
        Point a = new Point();
        a.setX(1);
        a.setY(2);

        Point b = new Point();
        b.setX(1);
        b.setY(2);

        log.info("a.equals(b) is " + a.equals(b));

    }
}

这个时候输出是true

把对象装入hashset进行比较

@Slf4j
public class EqualsHashDemo {


    public static void compare() {
        Point a = new Point();
        a.setX(1);
        a.setY(2);

        Point b = new Point();
        b.setX(1);
        b.setY(2);

        log.info("a.equals(b) is " + a.equals(b));

        HashSet<Point> points=new HashSet<>();
        points.add(a);

        log.info("points.contains(b) is " + points.contains(b)); 

    }
}

输出

 a.equals(b) is true
 points.contains(b) is false

这里就是因为没有重写hashcode导致的。没有重写,默认使用的是父类的hashcode,每个对象各不相同(hashset的实现暂时先不谈)

重写hashcode

class Point {
    private int x;
    private int y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)//ref相等
        {
            return true;
        }
        if (obj == null || this.getClass() != obj.getClass()) {
            return false;
        }
        Point that = (Point) obj;
        return x == that.x && y == that.y;//对比值
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}

再次运行

 a.equals(b) is true
 points.contains(b) is true

同样重写hashcode后下面的代码也能输出正常的值0000

  HashMap<Point, String> map = new HashMap<>();
        map.put(a, "00000");
        log.info(map.get(b));

如果不重新,则会输出null

 

以上是关于Java 重写equals的时候为什么一定要重写hashcode-一个例子的主要内容,如果未能解决你的问题,请参考以下文章

重写equals 方法的注意事项

如何重写hashCode()和equals()方法

java:放入Set中的对象一定要重写hashCode()和equals()吗?

java中重写Object类的equals方法为啥要重写hashcode方法?不重写可以吗?

请问各位大佬这道java的重写equals和重写hashcode方法内部是啥意思呀?

为什么重写equals方法一定要重写hashcode