Java 重写equals的时候为什么一定要重写hashcode…

2020-04-16 16:14:11来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

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

 


原文链接:https://www.cnblogs.com/Brake/p/12716839.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:HashMap源码分析

下一篇:java二维数组与稀疏数组的转换实现