目录
Set:无序不可重复的集合,只能根据元素本身来访问
Set接口常用的实现类有:HashSet、LinkedHashSet、TreeSet
关于常见的类方法,总结如下:
- 底层其实是包装了一个HashMap实现的
- 底层数据结构是数组+链表 + 红黑树
- 具有比较好的读取和查找性能, 可以有null 值
- 通过equals和HashCode来判断两个元素是否相等
- 非线程安全
- 继承HashSet,本质是LinkedHashMap实现
- 底层数据结构由哈希表(是一个元素为链表的数组)和双向链表组成。
- 有序的,根据HashCode的值来决定元素的存储位置,同时使用一个链表来维护元素的插入顺序
- 非线程安全
- 可以有null 值
- 底层是用TreeMap实现的,本质上是一个红黑树原理
- 排序分两种:自然排序和自定义排序
- 不能有null值,可通过重写Comparable接口有null值
- HashSet是Set接口的实现类,由哈希表支持,它不保证集合的迭代顺序;
- Hashset允许null元素;
- HashSet 是无序的,即不会记录插入的顺序;
- HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问;
代码实例
- // 初始化
- HashSet
language = new HashSet<>(); -
- // 添加元素
- System.out.println("------add()------");
- language.add("Java");
- language.add("Python");
- language.add("PHP");
- language.add("C++");
- System.out.println(language);
-
- language.add("Python");
- System.out.println("重复的元素不添加! " + language);
-
- // 包含
- System.out.println("------contains()------");
- System.out.println("contains(): " + language.contains("Java"));
- System.out.println("contains(): " + language.contains("C"));
-
- // 删除元素
- System.out.println("------remove()------");
- language.remove("C++");
- System.out.println(language);
-
- // for-each实现迭代
- System.out.println("------元素的迭代------");
- for (String l: language){
- System.out.println(l);
- }
- ------add()------
- [Java, C++, PHP, Python]
- 重复的元素不添加! [Java, C++, PHP, Python]
- ------contains()------
- contains(): true
- contains(): false
- ------remove()------
- [Java, PHP, Python]
- ------元素的迭代------
- Java
- PHP
- Python
- LinkedHashSet是HashSet的子类;
- LinkedHashSet底层是一个LinkedHashMap,底层维护了一个 数组+双向链表;
- LinkedHashSet 加入和取出元素的顺序一致;
- LinkedHashSet不是线程安全的,若多线程同时访问LinkedHashSet必须加锁,或通过使用Collections.SynchronizedSet;
EnumSet的用法请看Java学习笔记——枚举_柠檬不甜会酸的博客-CSDN博客
- TreeSet也是基于Map来实现,其底层结构为红黑树(特殊的二叉查找树);
- TreeSet具有排序功能,分为自然排序(123456)和自定义排序两类,默认是自然排序;
- TreeSet 继承于AbstractSet,所以它是一个Set集合,具有Set的属性和方法。
- TreeSet 实现了NavigableSet接口,意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。
- 对插入的元素进行排序,是一个有序的集合(主要与HashSet的区别);
- 允许插入Null值;
- 不允许插入重复元素;
- TreeSet是非线程安全的。
(1)TreeSet的创建
- // TreeSet
- TreeSet
treeSet = new TreeSet<>(); - System.out.println("TreeSet初始化容量的大小: " + treeSet.size());
TreeSet初始化容量的大小: 0
(2)添加元素
- // 添加元素
- treeSet.add(5);
- treeSet.add(10);
- treeSet.add(2);
- treeSet.add(-5);
- treeSet.add(3);
- treeSet.add(12);
- treeSet.add(100);
- treeSet.add(88);
- treeSet.add(99);
- System.out.println("------add()------");
- System.out.println("TreeSet容量大小: " + treeSet.size());
- System.out.println("TreeSet元素顺序为:" + treeSet.toString());
- ------add()------
- TreeSet容量大小: 9
- TreeSet元素顺序为:[-5, 2, 3, 5, 10, 12, 88, 99, 100]
(3)删除元素
- // 删除元素
- treeSet.remove(-5);
- System.out.println("------remove()------");
- System.out.println("TreeSet元素顺序为:" + treeSet.toString());
-
- int first = treeSet.pollFirst();
- int last = treeSet.pollLast();
- System.out.println("删除并返回第一个元素:如果set集合不存在元素,则返回null:" + first);
- System.out.println("删除并返回最后一个元素:如果set集合不存在元素,则返回null:" + last);
- System.out.println("TreeSet元素顺序为:" + treeSet.toString());
- ------remove()------
- TreeSet元素顺序为:[2, 3, 5, 10, 12, 88, 99, 100]
- 删除并返回第一个元素:如果set集合不存在元素,则返回null:2
- 删除并返回最后一个元素:如果set集合不存在元素,则返回null:100
- TreeSet元素顺序为:[3, 5, 10, 12, 88, 99]
(4)遍历
- // 遍历
- System.out.println("------for循环遍历------");
- for (int n: treeSet){
- System.out.println(n);
- }
-
- System.out.println("------升序------");
- Iterator
treeAsc = treeSet.iterator(); - while (treeAsc.hasNext()){
- int tmp = treeAsc.next();
- System.out.println("升序: " + tmp);
- }
-
- System.out.println("------降序------");
- Iterator
treeDec = treeSet.descendingIterator(); - while (treeDec.hasNext()){
- int tmp = treeDec.next();
- System.out.println("降序: " + tmp);
- }
- ------for循环遍历------
- 3
- 5
- 10
- 12
- 88
- 99
- ------升序------
- 升序: 3
- 升序: 5
- 升序: 10
- 升序: 12
- 升序: 88
- 升序: 99
- ------降序------
- 降序: 99
- 降序: 88
- 降序: 12
- 降序: 10
- 降序: 5
- 降序: 3
(5)访问
- // 访问
- System.out.println("------访问------");
- System.out.println("头部结点: " + treeSet.first());
- System.out.println("尾部结点: " + treeSet.last());
- System.out.println("获取指定元素之前的所有元素集合:(不包含指定元素): " + treeSet.headSet(12));
- System.out.println("获取指定元素之后的所有元素集合:(包含指定元素): " + treeSet.tailSet(12));
- System.out.println("获取给定元素之间的集合:(包含头,不包含尾): " + treeSet.subSet(0, 12));
- ------访问------
- 头部结点: 3
- 尾部结点: 99
- 获取指定元素之前的所有元素集合:(不包含指定元素): [3, 5, 10]
- 获取指定元素之后的所有元素集合:(包含指定元素): [12, 88, 99]
- 获取给定元素之间的集合:(包含头,不包含尾): [3, 5, 10]
(6)判断
- // 判断
- System.out.println("------判断------");
- System.out.println("treeSet是否为空: " + treeSet.isEmpty());
- System.out.println("treeSet是否包含12: " + treeSet.contains(12));
- ------判断------
- treeSet是否为空: false
- treeSet是否包含12: true
- import java.util.HashSet;
-
- public class Day30 {
- public static void main(String[] args){
- // 初始化
- HashSet
language = new HashSet<>(); -
- // 添加元素
- System.out.println("------add()------");
- language.add("Java");
- language.add("Python");
- language.add("PHP");
- language.add("C++");
- System.out.println(language);
-
- language.add("Python");
- System.out.println("重复的元素不添加! " + language);
-
- // 包含
- System.out.println("------contains()------");
- System.out.println("contains(): " + language.contains("Java"));
- System.out.println("contains(): " + language.contains("C"));
-
- // 删除元素
- System.out.println("------remove()------");
- language.remove("C++");
- System.out.println(language);
-
- // for-each实现迭代
- System.out.println("------元素的迭代------");
- for (String l: language){
- System.out.println(l);
- }
- }
- }
- import java.util.Iterator;
- import java.util.TreeSet;
-
- public class Day31 {
- public static void main(String[] args){
- // TreeSet
- TreeSet
treeSet = new TreeSet<>(); - System.out.println("TreeSet初始化容量的大小: " + treeSet.size());
-
- // 添加元素
- treeSet.add(5);
- treeSet.add(10);
- treeSet.add(2);
- treeSet.add(-5);
- treeSet.add(3);
- treeSet.add(12);
- treeSet.add(100);
- treeSet.add(88);
- treeSet.add(99);
- System.out.println("------add()------");
- System.out.println("TreeSet容量大小: " + treeSet.size());
- System.out.println("TreeSet元素顺序为:" + treeSet.toString());
-
- // 删除元素
- treeSet.remove(-5);
- System.out.println("------remove()------");
- System.out.println("TreeSet元素顺序为:" + treeSet.toString());
-
- int first = treeSet.pollFirst();
- int last = treeSet.pollLast();
- System.out.println("删除并返回第一个元素:如果set集合不存在元素,则返回null:" + first);
- System.out.println("删除并返回最后一个元素:如果set集合不存在元素,则返回null:" + last);
- System.out.println("TreeSet元素顺序为:" + treeSet.toString());
-
- // 遍历
- System.out.println("------for循环遍历------");
- for (int n: treeSet){
- System.out.println(n);
- }
-
- System.out.println("------升序------");
- Iterator
treeAsc = treeSet.iterator(); - while (treeAsc.hasNext()){
- int tmp = treeAsc.next();
- System.out.println("升序: " + tmp);
- }
-
- System.out.println("------降序------");
- Iterator
treeDec = treeSet.descendingIterator(); - while (treeDec.hasNext()){
- int tmp = treeDec.next();
- System.out.println("降序: " + tmp);
- }
-
- // 访问
- System.out.println("------访问------");
- System.out.println("头部结点: " + treeSet.first());
- System.out.println("尾部结点: " + treeSet.last());
- System.out.println("获取指定元素之前的所有元素集合:(不包含指定元素): " + treeSet.headSet(12));
- System.out.println("获取指定元素之后的所有元素集合:(包含指定元素): " + treeSet.tailSet(12));
- System.out.println("获取给定元素之间的集合:(包含头,不包含尾): " + treeSet.subSet(0, 12));
-
- // 判断
- System.out.println("------判断------");
- System.out.println("treeSet是否为空: " + treeSet.isEmpty());
- System.out.println("treeSet是否包含12: " + treeSet.contains(12));
- }
- }