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