HashSet底层存储原理

        HashSet<Student> set = new HashSet<>();
        Student aaa = new Student("aaa", 18);   //标记一
        set.add(aaa);
        set.add(new Student("bbb", 18));
        set.add(new Student("aaa", 18));       //标记二
        set.add(aaa);
        //Student类略,里面重写了equals和hashCode方法

问题一:标记一的对象和标记二的对象,他们的哈希值是一样的吗? 如何验证?


我对HashSet的理解如下:
底层哈希表结构(数组+链表+红黑树),由哈希表保证元素唯一,实际上是HashMap中value=null的实现.
哈希表的原理: 哈希表底层是数组+链表+红黑树,依赖于hashCode和equals方法
数组存储元素哈希值, 哈希值相同的存储在链表中,链表节点超过8个,链表换成红黑树,因为红黑树效率高


      存储元素时底层要做的判断:
      1.调用元素的hashCode()方法,遍历数组,有没有这个哈希值,没有就直接存储
      2.数组中已经有哈希值相同的,那么就调用元素的equals()方法,和哈希值相同的元素进行一一比较
      3.equals()方法比较,有相等的就不存储,不相等就存储
      

      

问题二: 请大佬帮我说一下哈希值是如何生成的?依据是什么?如果我的上述理解有误,请指出.

阅读 3.2k
3 个回答
问题一: 标记一的对象和标记二的对象,他们的哈希值是一样的吗? 如何验证?

不确定,虽然重写了 hashCode,但是并不知道里面写了什么逻辑…

问题二: 请大佬帮我说一下哈希值是如何生成的?依据是什么?如果我的上述理解有误,请指出.

哈希算法 算出来的,不同的数据类型不一样,比如 IntegerhashCode 就是自己的值,StringhashCode 是根据内容进行计算出来的,可以看一下这篇文章

修正:

  1.调用元素的hashCode()方法,遍历数组,有没有这个哈希值,没有就直接存储

不需要遍历,hashCode再计算一下就得到了数组下标,直接访问对应的数组元素

  • hashCode()方法的返回值就是它的哈希值
  • 没给hashCode()实现无法判断是否一样,是否一样自己调用一看便知

答案一:重写了hashCode方法,那么他们的哈希值是一样的,直接调用hashCode方法,就能看出来.

 另外补充一点,当重写了hashCode方法的时候,没有重写toString方法,打印对象的时候输出的不再是对象的地址值,而是通过哈希值计算出来的一个16进制值.
 

答案二:我还不知道

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题