问题
首先让我们先带着几个问题来进行接下来的学习
1.Set接口和List接口的区别是什么?
2.Set接口有什么特点?
3.Set接口的实现类有哪些?
接下来正式开始分析讲解Set接口
1.Set接口和List接口的区别是什么?
- List允许存储重复的元素, 而Set接口是不允许存在重复的元素的(元素可以为Null)
- List存储的数据是有序的(存入和取出一致), Set接口存储的数据是无序的(存入和取出不一致)
Set接口继承了Collection接口, 其继承了Collection的所有方法, 而Set接口比较常用的实现类有HashSet, LinkedHashSet, TreeSet,我们首先来看一段代码, 来感受Set接口中的元素不可重复
以TreeSet举例
通过代码,我们可以很直观的看到,我已经在TreeSet中添加了三条数据,其中两条数据相同,在打印输出的时候只输出了1和2,这就是Set接口的元素不可重复性,那么它的内部是怎么实现的呢?这个问题后边会有专门的介绍哦
那么接下来我们来看一下Set无序是什么意思
这里我们使用的是HashSet
可以看到插入的值和取出的值是不对应的,但是要注意,HashSet集合在自己的内部是有自己的排序的,而且随着我们插入顺序的变化,它内部的排序也会发生变化
2.Set接口有什么特点?
其实这个问题在前面早已进行了解答,细心地读者想必应该已经了解了吧,没错,就是无序性和不可重复性
3.Set接口的实现类基础理解
Set的实现类(常用)
- HashSet
- TreeSet
- LinkedHashSet
那么首先是第一个 HashSet
此类实现Set接口,由哈希表(实际为HashMap实例)支持。 对集合的迭代次序不作任何保证; 特别是,它不能保证数据在一段时间内保持不变。 这个类允许null元素。注意:HashSet是不同步的
HashSet的方法
- boolean add(E e)
将指定的元素添加到此集合(如果尚未存在)。 - void clear()
从此集合中删除所有元素。 - Object clone()
返回此 HashSet实例的浅层副本:元素本身不被克隆。 - boolean contains(Object o)
如果此集合包含指定的元素,则返回 true 。 - boolean isEmpty()
如果此集合不包含元素,则返回 true 。 - Iterator iterator()
返回此集合中元素的迭代器。 - boolean remove(Object o)
如果存在,则从该集合中删除指定的元素。 - int size()
返回此集合中的元素数(其基数)。 - Spliterator spliterator()
在此集合中的元素上创建late-binding和故障快速 Spliterator 。
因为元素顺序不固定的原因,我们无法使用HashSet来直接获取想要的数据,传入元素时,调用HashCode方法获取hash值,然后决定存储位置,我们可以来总结一下,HashSet对象中不能存储相同的数据,存储数据时是无序的。但是HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取的
代码演示
public class SetTest {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
// 添加元素
set.add("c");
set.add(