HashSet如何检查重复?为什么要重写hashCode和equals方法?

HashSet如何检查重复?为什么要重写hashCode和equals方法?

HashSet 底层维护了一个 HashMap,Map中的key是不允许重复的,HashSet正好利用了Map中的 Key不重复的特性 来校验重复元素

HashSet 添加元素(对象)时,HashSet (HashMap) 会先通过对象的 hashcode经过扰动函数 计算出 hash值 然后通过 (n - 1) & hash 判断对象加入的位置是否有元素,如果该位置为null,则直接存放到该位置;

如果不为null,则通过对象的 hash值equals方法 进行判断,判断它是否为重复元素,若重复,那么最后会将这个重复元素返回。(注意这里的hash值是经过运算处理后的hash值,不是真正的hashcode值

//hash的计算方法
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
//这段代码通过hash计算该元素的位置,判断是否有值; n为table数组的大小
if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
//该位置已有元素,接下来就通过hash和equals方法进行判断,是否为重复元素
if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;

所以经过上述代码所示,存放自定义对象时,一定要重写hashcode和equals方法来确保set中存放的不是重复的元素

为什么重写equals方法还要重写hashCode方法?

在HashSet、HashMap等中的key是用hashCode + equals()进行唯一性判断的,重写hashCode()方法,其底层是根据对象的属性值来生成新的hashCode,保证属性相同的对象的hashCode相等

如果不重写hashCode()方法,那么 相同属性值的两个对象可能出现不同的hashCode,那在HashSet、HashMap等中的key就不是唯一的了,可能出现相同的对象因为hashCode不同而存放在不同的位置

hashCode()equals() 的相关规定:

  1. 如果两个对象相等,则 hashcode 一定也是相同的
  2. 两个对象相等,对两个 equals() 方法判断 返回 true
  3. 两个对象有相同的 hashcode 值,它们也不一定是相等的
  4. 综上,equals() 方法被覆盖过,则 hashCode() 方法也必须被覆盖
  5. hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值