• 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中如何动态创建接口的实现
    使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务
    MyBatis中的@Mapper注解及配套注解使用详解(上)
    SpringMVC-DispatcherServlet工作流程及web.xml配置
    SpringMVC-DispatcherServlet配置(Spring-servlet.xml)
    Spring MVC 配置文件dispatcher-servlet.xml 文件详解
    python3 UnicodeEncodeError: 'gbk' codec can't encode character 'xa0' in position 30: illegal multibyte sequence
    python3之日期和时间(转载)
    python3 操作sqlSever
    python 抓取alexa数据
  • 原文地址:https://www.cnblogs.com/Brake/p/12716839.html
Copyright © 2020-2023  润新知