今天老师讲了HashSet这个集合,听了一下解决哈希冲突方法,就是有一个单向链表,计算哈希值之后会把计算好的值放在链表中,然后有重复的哈希值会在已有的哈希值上再连接一个链表,如图
当时我就不理解链表里为空的是什么,为什么会有空的值,然后就各种查资料,最后查到源代码中HashSet底部维护了一个HashMap,而这个HashMap底部又维护了一个默认长度为16的数组,所以没有插入的地方就是null
还有就是对这个链表又有了深入的了解,HashMap里面没有出现hash冲突时,没有形成单链表时,hashmap查找元素很快,get()方法能够直接定位到元素,但是出现单链表后,单个bucket 里存储的不是一个 哈希值,而是一个哈希值 链,系统只能必须按顺序遍历每个哈希值 链,直到找到想搜索的哈希值 为止——如果恰好要搜索的 哈希值 位于该哈希值 链的最末端(该哈希值 是最早放入该哈希值 中),那系统必须循环到最后才能找到该元素。
当创建 HashMap 时,有一个默认的负载因子(load factor),其默认值为 0.75,这是时间和空间成本上一种折衷:增大负载因子可以减少 Hash 表(就是那个默认长度为16的数组)所占用的内存空间,但会增加查询数据的时间开销,而查询是最频繁的的操作(HashMap 的 get() 与 put() 方法都要用到查询);减小负载因子会提高数据查询的性能,但会增加 Hash 表所占用的内存空间。 |