Java集合之HashSet

  HashSet 是哈希表实现。哈希表是一个特殊的数组,这个数组里存放的是链表(链表里存放的是符合条件的一组对象,条件是什么?下面会提到)。只要理解 HashSet 的 add 方法执行过程,就很容易理解 HashSet 了。

  当调用了 HashSet 的 add 方法存放对象 obj , HashSet 会首先调用 obj 的 hasCode 方法得到该对象的哈希码, HashSet 会使用一个算法把它的哈希码转换成一个数组下标,该下标“标记”了 obj 的位置。如果这个位置上的链表中没有元素,那么就把 obj 对象添加到链表上。如果这个位置上的链表中已经有了元素,则遍历这个链表,调用 obj 的 equals 方法,判断 obj 是否和其中的某个元素重复,如果没有重复的元素,那么就将 obj 添加到链表上;如果有重复的元素,则不会讲 obj 对象存入 HashSet 中。

  理解了 HashSet 的内部结构,我们再回头看看 equals 和 hashCode 方法。还记得那个约定吧?当我们重写了某个类的 equals 方法时,最好也重写该类的 hashCode 方法,并且应该遵守这样的约定:“如果两个对象不相等,那么它们的 hashCode 返回的整数不一定必须不等,但最好能为不相等的两个对象提供不同的 hashCode ,这样可以提高哈希表的性能。”为什么要有这样的约定?这样怎么就能提高哈希表性能了?我们用 HashSet 来作为例子分析一下(因为 HashSet 就是哈希表的实现)。如果我们写的某个类,重写了 equals 和 hashCode 方法,但写的很不好,就像约定中提到的那种情况,两个(或者多个)不相等的对象的 hashCode() 返回值相同。当我们往 HashSet 中添加这个类的对象时,HashSet 拿到 hashCode() 的返回值,分析哈希码,得到数组下标。但是由于对于不同的对象, hashCode 会有可能返回相同的哈希码,那么就会有可能,该数组下标下的链表中已经有了一个甚至多个元素。如果情况再糟糕一些,本应均匀分布在哈希表数组中的对象,分布在了几个链表中。最坏的情况是,所有对象的哈希码都相同,也就是说 hashCode 方法返回的是一个固定整数,那么哈希表就会变成了一个链表。还记得吗?链表的缺点是查询速度慢。那么 HashSet 的优势,查询速度快,已经不存在了。这就是所谓的降低了哈希表的性能。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值