• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

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

武飞扬头像
GQ学编程
帮助1

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 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfgikh
系列文章
更多 icon
同类精品
更多 icon
继续加载