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

猜你喜欢

转载自www.cnblogs.com/Brake/p/12716839.html