本篇目录
1- Set集合的特点
2- Set集合常用方法
3- HashSet
4- TreeSet
5- LinkedHashSet
Set集合特点
**继承关系:**从Set集合的继承图可以看到,它与List集合一样继承了Collection接口,说明Set集合也是一个单列集合。
**与List区别:**List的实现类都是有序的,而Set集合不一定有序。
**存储元素特点:**存储的元素不可重复,并且一般是允许存储NULL值的,除了TreeSet。
Set集合常用方法
向集合中添加一个元素,成功添加返回true,失败则返回false
set.add("测试数据")
从集合中删除一个元素,成功删除返回true,失败则返回false
set.remove("测试数据")
判断元素是否在Set集合中,存在返回true,不存在返回false
set.contains("测试数据")
返回Set集合存储元素的数量,返回一个数字,这个数字就是Set集合当前的大小
set.size()
以上就是Set集合的最基本的一些用法,如果有兴趣可以继续学习一下它的其他方法,如Set集合转数组、获取stream流等方法。
HashSet
HashSet是Set集合系列中最常用的,它的特点如下:无序、元素不可重复、可存储NULL值、非线程安全。
从HashSet的继承结构图中可以看到,Serializable
和Cloneable
接口依旧是标识性接口,分别标识可序列化和可克隆。继承的AbstractSet
抽象类则是将Set集合的一些共性方法抽取,以避免重复代码。
HashSet底层数据结构
从HashSet的add方法源码中可以看到如下代码
// HashSet集合的add方法
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
在HashSet的构造方法中可以看到,这里的map其实就是HashMap,HashSet的add方法其实就是借助的HashMap的put方法来添加元素的,如果添加的元素不存在,则返回的是null,则add方法返回true,标识添加元素成功。
// HashSet集合的构造方法
public HashSet() {
map = new HashMap<>();
}
如果还需要继续往下探究,就要再探究HashMap的底层了,有兴趣的可以查看这篇内容:https://mp.weixin.qq.com/s/8q032Yt5LMtFmraBb-9Z6A
TreeSet
TreeSet集合特点如下:无序但会处于排序状态、不允许添加NULL值、元素不可重复。
由TreeSet继承图可以看到,它还额外实现了NavigableSet
接口,而NavigableSet接口又实现了SortedSet
接口,所以这会使TreeMap集合元素处于排序的状态。
处于排序状态什么意思?如下代码中我依次向集合中添加的5、3、4、100、60五个数,最后遍历输出结果顺序为3、4、5、60、100。这也就证明了,TreeSet元素是会处于排序的状态。
Set<Integer> set = new TreeSet<>(); // 创建TreeSet对象
set.add(5); // 添加元素
set.add(3);
set.add(4);
set.add(100);
set.add(60);
// 遍历TreeSet元素并打印到控制台
for (Integer i : set) {
System.out.println(i);
}
TreeSet底层数据结构
由于TreeSet底层实现是红黑树
,所以默认整型排序为从小到大,这也就解释了为什么TreeSet元素会处于排序状态。红黑树的底层数据结构这使得TreeSet对元素的查找非常快捷。
TreeSet特有方法
返回集合的第一个元素,实现至SortedSet接口
set.first()
返回集合的最后一个元素,实现至SortedSet接口
set.last()
返回指定元素的前一个元素,实现至NavigableSet接口
set.lower("测试元素")
返回指定元素的后一个元素,实现至NavigableSet接口
set.higher("测试元素")
如上四个方法就是TreeSet集合常用的特有方法,这些方法HashSet是没有的。
LinkedHashSet
LinkedHashSet继承至HashSet,所以操作与HashSet基本无异,唯一的区别在于LinkedHashSet是有序的,原因是LinkedHashSet存储元素调用的是LinkedHashMap,使用了双向链表来维护元素先后次序。