欢迎访问宙启技术站
智能推送

Java面试题 从源码角度分析HashSet实现原理

发布时间:2023-05-14 11:47:08

HashSet是基于HashMap实现的,其中HashMap的实现原理就是哈希表。哈希表是一种以常数时间来执行插入、查找和删除操作的数据结构。在哈希表中,通过哈希函数将数据映射为表中的一个位置,这个位置称之为桶,然后在桶中查找对应的元素。

在HashMap中,键值对的键通过哈希函数计算出对应的哈希值,然后使用哈希值对数组的长度进行取余,得到插入位置。如果该位置已经有元素,就将该元素插入到链表或红黑树中。如果链表或红黑树的长度过长,就将其转化为红黑树或者扩容。

在HashSet中,只存储键值对中的键,因此它的实现与HashMap类似。HashSet通过哈希函数将元素映射为桶中的位置,然后将该元素插入到该位置中。如果该位置已经有元素,那么就进行比较,如果相同,则不插入,如果不同,就将该元素插入到链表或红黑树中。

在jdk1.8版本中,当链表或红黑树长度达到阈值时,会将其转化为红黑树或扩容。在扩容时,会先将容量扩大一倍,然后将每个桶中的元素重新计算位置,插入到新的桶中。这里的重新计算位置并不是简单的直接将原位置对新容量取摸,而是将原位置分成两部分,高位和低位,其中低位不变,高位计算出新的位置。这样做的原因是减少哈希冲突。

在jdk1.7版本中,一旦哈希冲突,就会采用链表来解决。在进行查找时,首先通过哈希函数计算桶的位置,然后遍历该桶中的链表,依次比较每个元素的哈希值和值是否与要查找的元素相同。如果相同,直接返回;如果链表遍历完了,仍然没有找到,则返回null。这种实现方式的缺点是,当链表长度过长时,会影响性能。

总之,HashSet的实现原理是基于哈希表的,通过哈希函数将元素映射为桶的位置,然后将元素插入到该位置中。在jdk1.8版本中,当链表或红黑树长度达到一定值时,会进行转化或扩容。而在jdk1.7版本中,只采用链表来处理哈希冲突。