重写了equals,还得重写hashCode

最典型的场景是针对HashMap

在重写equals和hashCode之前

@Slf4j
public class Oliver {
    public static void main(String[] args) {

        Map<People,String> pmap = Maps.newHashMap();
        People p1 = new People("123","Mary");
        People p2 = new People("123","Mary");

        pmap.put(p1,"1");

        System.out.println(pmap.get(p2));
    }
}

class People{
    private String idCard;
    private String name;

    public People(String idCard, String name) {
        this.idCard = idCard;
        this.name = name;
    }

    public String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

猜也能猜到…输出的是null
在这里插入图片描述

执行pmap.get(p2)的时候,步骤如下:
1、计算p2.hashCode获取哈希值
2、通过hash值在map的数组结构中找到p2的相应位置
3、找到位置后,通过equals方法遍历这个位置上的链表中所有数据直到找到p2

如下图,假如p2在哈希后找到了位置2上,而此时位置2上其实并没有p2要的数据(本来就没存过嘛)。
即使p2运气好,刚好跟p1一样落户到了位置3上,然后再位置3上通过equals方法跟p1对比,也无法得到p1的值,因为p1与p2在equals后必然是false。(equals默认比较内存地址)。

在这里插入图片描述
在这里p1,p2显然是同一个人身份证一样 ,名字也一样。
为了让hashMap知道他们是同一个人。
就按照规则同时重写equals和hashCode
比如直接使用idea帮我们生成:

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof People)) return false;
        People people = (People) o;
        return Objects.equals(getIdCard(), people.getIdCard()) &&
                Objects.equals(getName(), people.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getIdCard(), getName());
    }

在这里插入图片描述
再运行就能够通过p2拿到p1了。

如果使用lombok的@Data或@EqualsAndHashCode
注解,他会自己根据当前类的所有属性重写equals和hashCode。能够实现一样的效果。

发布了11 篇原创文章 · 获赞 2 · 访问量 340
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览