本文介绍: 无序: 存取的顺序不一样不重复可以去重无索引:不能使用普通for进行遍历,也不能通过索引获取元素Set集合实现类HashSet:无序,不重复,无索引,不重复,无索引,不重复,无索引

无序: 存取的顺序不一样

重复可以去重

索引:不能使用普通for进行遍历,也不能通过索引获取元素

Set集合实现

HashSet:无序,不重复,无索引

LinkedHashSet有序,不重复,无索引

TreeSet排序,不重复,无索引

Set一个接口,在方法基本和Collection一样

一.三种遍历

<1>迭代遍历

<2&gt;增强for

<3&gt;Lambda表达式

二.HashSet

HashSet在底层使用哈希存储数据

哈希表是一个对于增删查改数据比较好的数据结构

哈希表的组成:

JDK8以前:数组链表

JDK8开始:数组链表红黑树

在哈希表中一个重要的知识——哈希值

哈希值:对象整数形式

根据HashCode方法算出来的int类型整数

该方法定义在Object类中,所有对象可以调用默认使用地址值进行计算(所以意义不大)

一般情况下,会重写HashCode方法,利用对象内部属性计算哈希值

哈希值的特点

如果没用重写hashCode方法,不同对象计算出的哈希值是不同的

如果已经重写hashCode方法,不同对象只要属性值相同,计算出的哈希值就是一样的

在小部分情况下,不同的属性值或者不同的地址计算出来的哈希值也有可能是一样的(哈希碰撞

哈希碰撞  

一个极端例子:整形的范围是-21亿—+21亿加入有50亿个对象那么必然会有重复的

重写

重写

字符串内部自动重写hashCode

HashSet的底层原理

1.创建一个默认长度为16,默认加载因子为0.75的数组数组名字为table

2.根据元素的哈希值跟数组的长度计算应该存入的位置

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

4.如果位置不为null,表示有元素,则调用equals方法比较属性值

5.如果一样就不存入,如果不一样就存入

存入的方式有两种

JDK8以前:新元素存入数组,老元素挂在新元素下面

JDK8以后:新元素直接挂在老元素下面

加载因子

当数组的总量(默认是16)被填满了四分之三时(默认是16×0.75=12)就会扩容二倍

JDK8以后,当链表长度大于8并且数组的长度大于等于64时 当前链表自动转换红黑树

如果集合存储的是自定义的对象,必须重写hashCodeequals方法否则就会使用地址值比较

三个问腿

Q1:hashSet为什么存和取的顺序不一样

A:因为遍历是在数组的0索引开始遍历,可能是null,可能是链表,可能是红黑树,索引小的数据不一定是先添加的 

Q2:hashSet为什么没索引

A:因为hashSet里面包含链表 null 红黑树

Q3:hashSet是如何保证数据的去重呢

A:使用HashCode得到哈希值得到数据存储位置使用equals比较属性值

三.LinkedHashSet

有序,无索引,不重复

这里的有序指的是保证数据存储取出的元素一致

原理底层仍然是哈希表,只是每个元素又额外多了一个双链表的机制记录存储的数据

这样每两个相邻添加成功的数据,都会互相记录地址值,形成双向链表

LinkedHashSet遍历就是再双向链表的头节点开始遍历保证了数据存取一致

这个集合不为了效率,只保证顺序 

四.TreeSet

不重复,无索引,可排序

 底层是红黑树

原文地址:https://blog.csdn.net/Ineedmame/article/details/134698944

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_17725.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注