欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > Set集合系列——Set、HashSet、LinkedHashset、TreeSet

Set集合系列——Set、HashSet、LinkedHashset、TreeSet

2025/4/4 6:26:14 来源:https://blog.csdn.net/Eliaukgo/article/details/139804940  浏览:    关键词:Set集合系列——Set、HashSet、LinkedHashset、TreeSet

Set系列的公共特点:无重复、无索引,不可用普通for循环,API和Collection重复

HashSet:采取哈希表存取数据

哈希表组成?

JDk8之前:数组+链表, JDK8以后:数组+链表+红黑树

哈希值?

利用HashCode方法计算出来的对象的int表达形式,哈希值的作用是,根据对象的哈希值计算出在数组中的存放的索引位置,如下图公式,这样存取都很快,hashCode默认是通过对象内存地址映射过来的

哈希值的特点?

何时以及为什么要重写hashcode和equals方法?

当对象是String,Integer时不需要重写,源码已经重写了;

当集合中存储的对象为自定义对象,必须重写hashCode和equals方法!!!

因为hashCode默认是通过对象内存地址映射过来的,我们想要用属性值来计算哈希值,所以重写

因为equals默认比较的是地址值,我们想要比较的是内部属性值,同时,重写equals也是防止哈希冲突造来的影响,所以重写。

HashSet添加元素过程在JDK8以前的底层原理?

1、首先自动创建一个默认长度16,默认加载因子为0.75(扩容时机)的数组table

2、调用hashcode方法,根据元素的哈希值和数组长度计算出要存入的位置

3、判断当前位置是否为null如果空,直接存入

4、如果非空,调用equals方法比较属性值

5、一样的话不存,不一样的话代替老元素存入数组位置,并将老元素挂在新元素下面,形成链表

HashSet添加元素过程在JDK8以后的底层原理?

1,2,3,4和JDK8以前一样

5、一样的话不存,不一样的话老元素不动,并将新元素挂在老元素下面,形成链表

扩容时机?

元素会越存越多,当存入16*0.75=12个元素时,数组会扩容到原先2倍,16——32.

在JDK8以后:链表长度超过8,且数组长度大于等于64时,自动转为红黑树

在JDK8以后,数组+链表+红黑树。

HashSet的几个问题?

1、HashSet存和取顺序为何不同?

存入位置是靠哈希值确定的,所以存入的顺序和元素在数组中的顺序无关;在取的时候,从默认数组table的0索引位进行遍历,但是,这个遍历位置和存入顺序无关,无法确定他是否是第一个存入的。

2、HashSet为什么没有索引?

因为在哈希表中可能存在链表,数组的一个索引只能代表一条链表,而链表上存在许多元素,无法表示出来这些元素的索引。因为底层的结构不唯一,结构太多导致于确定索引比较困难,所以舍弃了索引机制

3、HashSet利用什么保证数据去重?

利用Hashcode得到哈希值,获取元素在数组中的位置;然后利用equals比较对象属性值是否相同

4、HashSet的底层数据结构?

JDk8之前:数组+链表, JDK8以后:数组+链表+红黑树

5、HashSet好处

用Hashset写数据校验很方便,通过add的返回值判断数据有无重复然后返回不同的提示

LinkedHashset:有序——存入和取出顺序相同

利用双向链表记录存储顺序,从而达到有序

如果要用数据去重,用HashSet还是LinkedHashSet?

因为linkedHashset在Hashset基础上多做了事情,效率较低

TreeSet:可排序

1、什么是可排序?

 可以按照元素的默认规则(由小到大)进行排序

2、默认排序规则是什么?(数值)

遇到字符串组合情况,一位一位的对应比较ASCII码表:

3、TreeSet集合底层数据结构是什么?

基于红黑树的数据结构实现排序的,增删改查性能都较好

4、除了普通for遍历不可以使用,其他均可以遍历

5、非默认的排序规则(2种):存储的对象为自定义对象

第一种:重写Comparable接口中的抽象方法(默认)

例子:创建自定义学生对象,并按照年龄大小排序

在不进行任何操作下,直接add学生对象:系统报错,因为无法按照规则排序

进行重写方法:

重写Comparable接口中的抽象方法的具体原理:o表示已有的数据,this为插入数据

按照add的顺序,构造红黑树,按照红黑树的红黑规则

看看TreeSet如何进行的排序:

对重写Comparable接口中的抽象方法进行打印this和o:

结果:

add的顺序:

可以看出o就是红黑树原来存储的元素,this为新添加的元素,添加过程按照红黑树的红黑规则

第二种:创建TreeSet对象时,传递比较器Comparator指定规则

格式?

何时使用?

在第一种方法不满足要求后使用,比如字符串String已经默认重写了Compareto方法,如果我们不想按照默认方法,但又不方便修改源码,则需要利用这种方法来重新定义排序规则,两种方法同时存在时,听比较器Comparator的指定规则。

例题1:TreeSet对象排序,string数据类型,按长度排序(非默认)

如果要降序排列:return -i;

TreeSet小结

6、TreeSet无需重写hashCode和equals方法,不依托哈希表

7、各种set实现类怎么选择使用?

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词