快速建网站模板,html5网页成品代码,洛阳400电话洛阳网站seo,电商平台网站定制目录一、集合框架层次结构二、Collection集合1、Set集合1、HashSet2、LinkedHashSet3、TreeSet4、ConcurrentSkipListSet5、CopyOnWriteArraySetJava 集合框架#xff08;Collections Framework#xff09;是 Java 中用于
存储和操作数据组的重要架构。它提供了一组接口、实现…目录一、集合框架层次结构二、Collection集合1、Set集合1、HashSet2、LinkedHashSet3、TreeSet4、ConcurrentSkipListSet5、CopyOnWriteArraySetJava 集合框架Collections Framework是 Java 中用于存储和操作数据组的重要架构。它提供了一组接口、实现类和算法。一、集合框架层次结构Collection (接口) ├── List (接口 - 有序可重复) │ ├── ArrayList (实现类) │ ├── LinkedList (实现类) │ ├── Vector (线程安全已过时) │ └── Stack (继承Vector) │ ├── Set (接口 - 无序不可重复) │ ├── HashSet (实现类) │ │ └── LinkedHashSet (保持插入顺序) │ ├── SortedSet (接口) │ │ └── TreeSet (实现类) │ └── EnumSet (专用于枚举) │ └── Queue (接口 - 队列) ├── Deque (双端队列接口) │ ├── ArrayDeque (实现类) │ └── LinkedList (也实现了Deque) │ ├── PriorityQueue (优先队列) └── BlockingQueue (阻塞队列接口) ├── ArrayBlockingQueue ├── LinkedBlockingQueue └── PriorityBlockingQueue Map (接口 - 键值对) ├── HashMap (实现类) │ └── LinkedHashMap (保持插入顺序) ├── TreeMap (基于红黑树) ├── Hashtable (线程安全已过时) ├── WeakHashMap (弱引用) └── ConcurrentHashMap (并发版)Java集合大致可以分为两大体系一个是Collection另一个是MapCollection主要由List、Set、Queue接口组成List代表有序、重复的集合其中Set代表无序、不可重复的集合Queue体系集合代表一种队列集合实现。Map则代表具有映射关系的键值对集合。java.util.Collection下的接口和继承类关系简易结构图java.util.Map下的接口和继承类关系简易结构图其中Java 集合框架中主要封装的是典型的数据结构和算法如动态数组、双向链表、队列、栈、Set、Map等。二、Collection集合通过集合的关系图我们可以知道Collection是集合的顶层父类他定义了集合的基本方法如基本操作方法方法签名功能描述返回值示例时间复杂度int size()返回集合中元素的数量元素个数list.size()→3O(1)boolean isEmpty()判断集合是否为空true/falselist.isEmpty()→falseO(1)boolean contains(Object o)判断是否包含指定元素true/falselist.contains(A)→trueList: O(n)Set: O(1)TreeSet: O(log n)boolean add(E e)添加元素到集合是否成功list.add(D)→trueArrayList: 均摊O(1)LinkedList: O(1)TreeSet: O(log n)boolean remove(Object o)移除指定元素是否成功list.remove(A)→trueArrayList: O(n)LinkedList: O(n)HashSet: O(1)批量操作方法方法签名功能描述返回值示例说明boolean containsAll(Collection? c)是否包含集合c中所有元素true/falselist.containsAll(subList)检查子集关系boolean addAll(Collection? extends E c)添加集合c中所有元素是否改变list.addAll(anotherList)批量添加boolean removeAll(Collection? c)移除集合c中所有元素是否改变list.removeAll(toRemove)差集操作boolean retainAll(Collection? c)仅保留集合c中元素是否改变list.retainAll(common)交集操作void clear()清空集合所有元素无list.clear()集合变为空转换和迭代方法方法签名功能描述返回值示例说明Object[] toArray()转换为Object数组Object数组list.toArray()返回新数组T T[] toArray(T[] a)转换为指定类型数组指定类型数组list.toArray(new String[0])类型安全转换IteratorE iterator()返回迭代器Iterator对象list.iterator()用于遍历集合default boolean removeIf(Predicate? super E filter)条件删除是否改变list.removeIf(s - s.length() 3)Java 8default SpliteratorE spliterator()返回分割迭代器Spliterator对象list.spliterator()Java 8并行遍历default StreamE stream()返回顺序流Stream对象list.stream()Java 8流操作default StreamE parallelStream()返回并行流Stream对象list.parallelStream()Java 8并行流操作集合运算方法方法数学运算示意图示例addAll()并集A ∪ BA.addAll(B)retainAll()交集A ∩ BA.retainAll(B)removeAll()差集A - BA.removeAll(B)常见操作示例操作需求代码示例说明遍历集合for (E e : collection) { ... }增强for循环安全遍历并删除iterator.remove()使用迭代器删除转换为数组String[] arr coll.toArray(new String[0])推荐写法批量添加元素coll.addAll(Arrays.asList(A,B,C))初始化集合过滤集合coll.removeIf(e - e.startsWith(A))Java 8集合判空if (!coll.isEmpty()) { ... }优于size() 0注意事项表格方法注意事项推荐做法contains()依赖equals()和hashCode()正确实现这两个方法remove(Object)只删除第一个匹配项使用removeIf()删除所有toArray()无参方法返回Object[]使用带参方法指定类型addAll()可能修改原集合注意并发修改异常clear()不释放元素引用大集合考虑设为nulliterator()遍历时不能修改集合使用迭代器的remove()场景建议理由频繁包含检查使用HashSetO(1)时间复杂度频繁插入删除使用LinkedList首尾操作O(1)随机访问使用ArrayListO(1)索引访问需要排序使用TreeSet自动维护顺序线程安全使用并发集合ConcurrentHashMap等只读操作使用不可变集合Collections.unmodifiableXXX()Collection集合中所包含的方法publicinterfaceCollectionEextendsIterableE{// 基本操作方法intsize();booleanisEmpty();booleancontains(Objecto);booleanadd(Ee);booleanremove(Objecto);// 批量操作booleancontainsAll(Collection?c);booleanaddAll(Collection?extendsEc);booleanremoveAll(Collection?c);booleanretainAll(Collection?c);voidclear();// 数组转换Object[]toArray();TT[]toArray(T[]a);// 迭代器IteratorEiterator();// Java 8 新增方法defaultbooleanremoveIf(Predicate?superEfilter){...}defaultSpliteratorEspliterator(){...}defaultStreamEstream(){...}defaultStreamEparallelStream(){...}}1、Set集合Set集合的特点元素不重复存取无序无下标SetE (接口) ├── HashSetE (实现类) │ └── LinkedHashSetE (子类) ├── SortedSetE (接口) │ └── TreeSetE (实现类) ├── EnumSetE (实现类) └── CopyOnWriteArraySetE (并发实现)Set 接口核心特性特性说明唯一性不允许重复元素无序性不保证插入顺序除LinkedHashSet允许null大多数实现允许一个null元素数学运算支持并集、交集、差集等操作无索引不能通过索引访问元素1、HashSet一个标准的Set集合底层是使用HashMap的Key实现的,特点为:线程不安全,不可重复,无序。HashSet是Java中最常用的Set实现基于HashMap实现具有快速查找、插入和删除的特性。底层实现原理publicclassHashSetEextendsAbstractSetEimplementsSetE,Cloneable,java.io.Serializable{// 底层使用 HashMap 存储privatetransientHashMapE,Objectmap;// 所有元素共享的虚拟值privatestaticfinalObjectPRESENTnewObject();// 构造方法publicHashSet(){mapnewHashMap();// 默认初始容量16加载因子0.75}publicHashSet(intinitialCapacity){mapnewHashMap(initialCapacity);}publicHashSet(intinitialCapacity,floatloadFactor){mapnewHashMap(initialCapacity,loadFactor);}}核心特性特性说明底层实现基于 HashMap元素作为Key唯一性不允许重复元素无序性不保证插入顺序允许null允许一个null元素线程安全非线程安全性能O(1) 的基本操作平均情况扩容默认初始容量16加载因子0.75构造方法详解// 1. 默认构造容量16加载因子0.75HashSetStringset1newHashSet();// 2. 指定初始容量HashSetStringset2newHashSet(100);// 初始容量100// 3. 指定初始容量和加载因子HashSetStringset3newHashSet(100,0.8f);// 初始容量100加载因子0.8// 4. 从集合构造ListStringlistArrays.asList(A,B,C,A);HashSetStringset4newHashSet(list);// 自动去重[A, B, C]// 5. 特殊构造包访问权限用于LinkedHashSet// HashSet(int initialCapacity, float loadFactor, boolean dummy)添加元素// HashSet的add方法实际调用HashMap的put方法publicbooleanadd(Ee){returnmap.put(e,PRESENT)null;}// HashMap.put() 方法的核心逻辑// 1. 计算key的hash值// 2. 找到对应的桶bucket// 3. 如果桶为空直接插入// 4. 如果桶不为空遍历链表/红黑树// 5. 找到相同keyequals为true则替换值// 6. 未找到则添加到链表/树末尾删除元素publicbooleanremove(Objecto){returnmap.remove(o)PRESENT;}// 实际调用HashMap.remove()查找元素publicbooleancontains(Objecto){returnmap.containsKey(o);}基本操作// 创建HashSetHashSetStringfruitsnewHashSet();// 1. 添加元素fruits.add(Apple);fruits.add(Banana);fruits.add(Orange);fruits.add(Apple);// 重复元素不会添加fruits.add(null);// 允许nullSystem.out.println(fruits);// [null, Apple, Banana, Orange]// 2. 检查元素booleanhasApplefruits.contains(Apple);// truebooleanhasGrapefruits.contains(Grape);// falsebooleanisEmptyfruits.isEmpty();// false// 3. 删除元素fruits.remove(Banana);// 删除成功返回truefruits.remove(Watermelon);// 元素不存在返回falsefruits.remove(null);// 删除null元素// 4. 获取大小intsizefruits.size();// 2// 5. 清空集合fruits.clear();System.out.println(fruits);// []遍历方式HashSetStringsetnewHashSet();set.addAll(Arrays.asList(A,B,C,D,E));// 1. 增强for循环for(Stringitem:set){System.out.println(item);}// 2. 迭代器IteratorStringiteratorset.iterator();while(iterator.hasNext()){Stringitemiterator.next();System.out.println(item);// iterator.remove(); // 可以在迭代时删除}// 3. Java 8 forEachset.forEach(System.out::println);// 4. 转换为数组遍历Object[]arrayset.toArray();for(Objectobj:array){System.out.println(obj);}// 5. 转换为流处理set.stream().filter(s-s.startsWith(A)).forEach(System.out::println);集合运算HashSetIntegersetAnewHashSet(Arrays.asList(1,2,3,4,5));HashSetIntegersetBnewHashSet(Arrays.asList(4,5,6,7,8));// 1. 并集HashSetIntegerunionnewHashSet(setA);union.addAll(setB);System.out.println(并集: union);// [1, 2, 3, 4, 5, 6, 7, 8]// 2. 交集HashSetIntegerintersectionnewHashSet(setA);intersection.retainAll(setB);System.out.println(交集: intersection);// [4, 5]// 3. 差集 (A - B)HashSetIntegerdifferencenewHashSet(setA);difference.removeAll(setB);System.out.println(差集A-B: difference);// [1, 2, 3]// 4. 对称差集 (A ∪ B - A ∩ B)HashSetIntegersymmetricDiffnewHashSet(setA);symmetricDiff.addAll(setB);// 先并集HashSetIntegertmpnewHashSet(setA);tmp.retainAll(setB);// 交集symmetricDiff.removeAll(tmp);// 减去交集System.out.println(对称差集: symmetricDiff);// [1, 2, 3, 6, 7, 8]// 5. 子集判断booleanisSubsetsetA.containsAll(newHashSet(Arrays.asList(1,2)));// truebooleanisSupersetnewHashSet(Arrays.asList(1,2,3,4,5,6)).containsAll(setA);// true2、LinkedHashSetLinkedHashSet是HashSet的子类在HashSet的基础上维护了元素的插入顺序通过双向链表记录插入顺序。底层实现原理publicclassLinkedHashSetEextendsHashSetEimplementsSetE,Cloneable,java.io.Serializable{// 继承自HashSet底层使用LinkedHashMap// 构造方法调用父类的特殊构造publicLinkedHashSet(){super(16,0.75f,true);// 关键dummy参数为true}}// HashSet中的特殊构造方法HashSet(intinitialCapacity,floatloadFactor,booleandummy){mapnewLinkedHashMap(initialCapacity,loadFactor);}LinkedHashMap 结构publicclassLinkedHashMapK,VextendsHashMapK,V{// 双向链表节点staticclassEntryK,VextendsHashMap.NodeK,V{EntryK,Vbefore,after;// 前后指针Entry(inthash,Kkey,Vvalue,NodeK,Vnext){super(hash,key,value,next);}}// 链表头尾transientLinkedHashMap.EntryK,Vhead;transientLinkedHashMap.EntryK,Vtail;// 访问顺序标志finalbooleanaccessOrder;}核心特性特性LinkedHashSetHashSetTreeSet底层实现LinkedHashMapHashMapTreeMap唯一性✅ 不允许重复✅ 不允许重复✅ 不允许重复顺序性✅ 插入顺序❌ 无序✅ 自然排序允许null✅ 允许一个null✅ 允许一个null❌ 不允许null线程安全❌ 非线程安全❌ 非线程安全❌ 非线程安全性能O(1) 基本操作O(1) 基本操作O(log n) 基本操作内存开销较高维护链表较低中等构造方法详解// 1. 默认构造容量16加载因子0.75LinkedHashSetStringset1newLinkedHashSet();// 2. 指定初始容量LinkedHashSetStringset2newLinkedHashSet(100);// 3. 指定初始容量和加载因子LinkedHashSetStringset3newLinkedHashSet(100,0.8f);// 4. 从集合构造保持原集合的顺序ListStringlistArrays.asList(C,A,B,C,A);LinkedHashSetStringset4newLinkedHashSet(list);// 顺序[C, A, B]去重保持第一次出现的顺序// 特殊通过Collections.newSetFromMap()SetStringsynchronizedSetCollections.newSetFromMap(newLinkedHashMapString,Boolean());基本操作// 创建LinkedHashSetLinkedHashSetStringfruitsnewLinkedHashSet();// 1. 添加元素保持插入顺序fruits.add(Apple);fruits.add(Banana);fruits.add(Orange);fruits.add(Apple);// 重复不添加fruits.add(Grape);fruits.add(null);// 允许nullSystem.out.println(fruits);// 输出[Apple, Banana, Orange, Grape, null]保持插入顺序// 2. 遍历验证顺序System.out.println(遍历顺序);for(Stringfruit:fruits){System.out.println(fruit);// Apple, Banana, Orange, Grape, null}// 3. 删除元素不会影响其他元素的顺序fruits.remove(Banana);System.out.println(删除Banana后fruits);// [Apple, Orange, Grape, null]// 4. 插入新元素添加到末尾fruits.add(Peach);System.out.println(添加Peach后fruits);// [Apple, Orange, Grape, null, Peach]// 5. 重新添加已存在元素位置不变fruits.add(Apple);// Apple已存在位置不变System.out.println(重新添加Apple后fruits);// [Apple, Orange, Grape, null, Peach]顺序不变迭代器特性LinkedHashSetIntegersetnewLinkedHashSet();for(inti1;i5;i){set.add(i);}// 迭代器按插入顺序遍历IteratorIntegeriteratorset.iterator();System.out.print(迭代器输出);while(iterator.hasNext()){System.out.print(iterator.next() );// 1 2 3 4 5}System.out.println();// 列表迭代器LinkedHashSet没有直接提供但可以通过转换ListIntegerlistnewArrayList(set);ListIteratorIntegerlistIteratorlist.listIterator();while(listIterator.hasNext()){System.out.print(listIterator.next() );}集合运算保持顺序LinkedHashSetIntegersetAnewLinkedHashSet();Collections.addAll(setA,1,3,5,7,9);LinkedHashSetIntegersetBnewLinkedHashSet();Collections.addAll(setB,2,4,6,8,5,7);// 并集保持setA和setB的插入顺序LinkedHashSetIntegerunionnewLinkedHashSet(setA);union.addAll(setB);// setB的元素按setB的顺序添加到末尾System.out.println(并集union);// [1, 3, 5, 7, 9, 2, 4, 6, 8]// 交集保持setA的顺序LinkedHashSetIntegerintersectionnewLinkedHashSet(setA);intersection.retainAll(setB);System.out.println(交集intersection);// [5, 7]保持setA中的顺序// 差集保持setA的顺序LinkedHashSetIntegerdifferencenewLinkedHashSet(setA);difference.removeAll(setB);System.out.println(差集difference);// [1, 3, 9]保持setA中的顺序3、TreeSetTreeSet是基于红黑树Red-Black Tree 实现的 NavigableSet元素自动排序且不允许重复。底层实现原理publicclassTreeSetEextendsAbstractSetEimplementsNavigableSetE,Cloneable,java.io.Serializable{// 底层使用 TreeMapprivatetransientNavigableMapE,Objectm;// 虚拟值privatestaticfinalObjectPRESENTnewObject();// 构造方法publicTreeSet(){this(newTreeMapE,Object());// 自然排序}publicTreeSet(Comparator?superEcomparator){this(newTreeMap(comparator));// 定制排序}}红黑树特性// TreeMap 中的红黑树节点staticfinalclassEntryK,VimplementsMap.EntryK,V{Kkey;Vvalue;EntryK,Vleft;// 左子树EntryK,Vright;// 右子树EntryK,Vparent;// 父节点booleancolorBLACK;// 颜色红/黑// 红黑树五大特性// 1. 节点是红色或黑色// 2. 根节点是黑色// 3. 所有叶子节点NIL是黑色// 4. 红色节点的两个子节点都是黑色// 5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点}核心特性特性TreeSetHashSetLinkedHashSet底层结构红黑树哈希表哈希表链表排序方式自然排序/定制排序无顺序插入顺序时间复杂度O(log n)O(1)O(1)允许null❌除非指定Comparator✅✅线程安全❌❌❌内存开销较高较低中等范围查询✅ 支持❌❌构造方法详解// 1. 默认构造自然排序TreeSetIntegerset1newTreeSet();// 元素必须实现Comparable接口// 2. 指定ComparatorTreeSetStringset2newTreeSet(Comparator.reverseOrder());// 3. 从集合构造使用自然排序ListIntegerlistArrays.asList(5,2,8,1,9);TreeSetIntegerset3newTreeSet(list);// 自动排序[1, 2, 5, 8, 9]// 4. 从SortedSet构造保持原有排序SortedSetIntegersortednewTreeSet(Comparator.reverseOrder());sorted.addAll(Arrays.asList(5,2,8));TreeSetIntegerset4newTreeSet(sorted);// 保持逆序[8, 5, 2]// 5. 使用NavigableMap构造NavigableMapString,ObjectmapnewTreeMap();TreeSetStringset5newTreeSet(map);元素排序规则自然排序Comparable// 元素类必须实现Comparable接口classStudentimplementsComparableStudent{privateStringname;privateintscore;publicStudent(Stringname,intscore){this.namename;this.scorescore;}OverridepublicintcompareTo(Studentother){// 先按分数排序分数相同按姓名排序intscoreCompareInteger.compare(this.score,other.score);if(scoreCompare!0){returnscoreCompare;}returnthis.name.compareTo(other.name);}OverridepublicStringtoString(){returnname:score;}}// 使用TreeSetStudentstudentsnewTreeSet();students.add(newStudent(Alice,85));students.add(newStudent(Bob,92));students.add(newStudent(Charlie,78));students.add(newStudent(David,85));// 分数相同按姓名排序System.out.println(students);// [Charlie:78, Alice:85, David:85, Bob:92]定制排序Comparator// 1. 字符串长度排序TreeSetStringbyLengthnewTreeSet(Comparator.comparing(String::length).thenComparing(String::compareTo));byLength.addAll(Arrays.asList(Apple,Banana,Cat,Dog,Elephant));System.out.println(byLength);// [Cat, Dog, Apple, Banana, Elephant]// 2. 逆序排序TreeSetIntegerreversednewTreeSet(Comparator.reverseOrder());reversed.addAll(Arrays.asList(5,2,8,1,9));System.out.println(reversed);// [9, 8, 5, 2, 1]// 3. 复杂对象多字段排序classProduct{Stringname;doubleprice;intstock;}TreeSetProductproductsnewTreeSet(Comparator.comparing(Product::getPrice).thenComparing(Product::getName).thenComparingInt(Product::getStock));// 4. 处理null值TreeSetStringwithNullsnewTreeSet(Comparator.nullsFirst(String::compareTo));withNulls.add(null);withNulls.add(Apple);withNulls.add(Banana);System.out.println(withNulls);// [null, Apple, Banana]基本操作// 创建TreeSetTreeSetStringfruitsnewTreeSet();// 1. 添加元素自动排序fruits.add(Orange);fruits.add(Apple);fruits.add(Banana);fruits.add(Apple);// 重复元素不会添加// fruits.add(null); // 抛出NullPointerException默认情况下System.out.println(fruits);// [Apple, Banana, Orange]// 2. 遍历按排序顺序for(Stringfruit:fruits){System.out.println(fruit);// Apple, Banana, Orange}// 3. 删除元素fruits.remove(Banana);System.out.println(fruits);// [Apple, Orange]// 4. 清空集合fruits.clear();System.out.println(fruits.isEmpty());// true范围查询操作TreeSetIntegernumbersnewTreeSet();for(inti1;i10;i){numbers.add(i);}// 子集操作SortedSetIntegerheadSetnumbers.headSet(5);// [1, 2, 3, 4]SortedSetIntegertailSetnumbers.tailSet(6);// [6, 7, 8, 9, 10]SortedSetIntegersubSetnumbers.subSet(3,7);// [3, 4, 5, 6]// 包含边界控制SortedSetIntegerheadSetInclusivenumbers.headSet(5,true);// [1, 2, 3, 4, 5]SortedSetIntegersubSetExclusivenumbers.subSet(3,false,7,false);// [4, 5, 6]// 获取范围内的元素闭区间NavigableSetIntegerrangenumbers.subSet(2,true,8,true);System.out.println(2到8的范围: range);// [2, 3, 4, 5, 6, 7, 8]导航方法TreeSetIntegersetnewTreeSet(Arrays.asList(2,4,6,8,10));// 获取首尾元素Integerfirstset.first();// 2Integerlastset.last();// 10// 小于/小于等于Integerlowerset.lower(5);// 4小于5的最大元素Integerfloorset.floor(5);// 4小于等于5的最大元素IntegerfloorExactset.floor(4);// 4// 大于/大于等于Integerhigherset.higher(5);// 6大于5的最小元素Integerceilingset.ceiling(5);// 6大于等于5的最小元素IntegerceilingExactset.ceiling(4);// 4// 弹出首尾元素IntegerpollFirstset.pollFirst();// 2并从集合移除IntegerpollLastset.pollLast();// 10并从集合移除System.out.println(弹出后: set);// [4, 6, 8]4、ConcurrentSkipListSetConcurrentSkipListSet是基于跳表Skip List实现的线程安全的有序集合是TreeSet 的并发版本底层实现原理跳表数据结构// 跳表节点结构staticfinalclassNodeK,V{finalKkey;volatileObjectvalue;volatileNodeK,Vnext;// 索引层volatileIndexK,V[]indices;}// 索引层结构staticclassIndexK,V{finalNodeK,Vnode;// 引用的数据节点finalIndexK,Vdown;// 下层索引volatileIndexK,Vright;// 右侧索引Index(NodeK,Vnode,IndexK,Vdown,IndexK,Vright){this.nodenode;this.downdown;this.rightright;}}跳表示意图Level 3: head ------------------------ 50 ------------------------ tail ↓ ↓ ↓ Level 2: head ------------ 30 ------------ 50 ------------ 70 --- tail ↓ ↓ ↓ ↓ ↓ Level 1: head ---- 10 ---- 30 ---- 40 ---- 50 ---- 60 ---- 70 --- tail ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ Level 0: head - 10 - 20 - 30 - 40 - 50 - 60 - 70 - 80 - 90 - tail核心特性特性ConcurrentSkipListSetTreeSetCopyOnWriteArraySet底层结构跳表Skip List红黑树动态数组线程安全✅ 是无锁CAS❌ 否✅ 是有序性✅ 自然排序✅ 自然排序❌ 无序并发性能✅ 高读多写多❌ 低✅ 读多写少时间复杂度O(log n)O(log n)读O(1)写O(n)允许null❌ 不允许❌ 不允许✅ 允许内存开销中等较高高构造方法// 1. 默认构造自然排序ConcurrentSkipListSetIntegerset1newConcurrentSkipListSet();// 2. 指定ComparatorConcurrentSkipListSetStringset2newConcurrentSkipListSet(Comparator.reverseOrder());// 3. 从集合构造ListIntegerlistArrays.asList(5,2,8,1,9);ConcurrentSkipListSetIntegerset3newConcurrentSkipListSet(list);// 自动排序[1, 2, 5, 8, 9]// 4. 从SortedSet构造SortedSetIntegersortednewTreeSet();sorted.addAll(Arrays.asList(5,2,8));ConcurrentSkipListSetIntegerset4newConcurrentSkipListSet(sorted);基本操作ConcurrentSkipListSetStringsetnewConcurrentSkipListSet();// 1. 并发添加元素Threadt1newThread(()-{set.add(Apple);set.add(Banana);});Threadt2newThread(()-{set.add(Orange);set.add(Apple);// 重复元素不会添加});t1.start();t2.start();t1.join();t2.join();System.out.println(set);// [Apple, Banana, Orange]已排序// 2. 安全遍历for(Stringfruit:set){System.out.println(fruit);// 线程安全遍历}// 3. 删除元素booleanremovedset.remove(Banana);System.out.println(删除Banana: removed);// true// 4. 清空集合set.clear();System.out.println(是否为空: set.isEmpty());// true并发操作示例publicclassConcurrentSetExample{privatefinalConcurrentSkipListSetIntegernumbersnewConcurrentSkipListSet();privatefinalintTHREAD_COUNT10;privatefinalintOPERATIONS_PER_THREAD1000;publicvoidconcurrentTest()throwsInterruptedException{ListThreadthreadsnewArrayList();// 创建生产者线程for(inti0;iTHREAD_COUNT;i){finalintthreadIdi;ThreadproducernewThread(()-{RandomrandomnewRandom();for(intj0;jOPERATIONS_PER_THREAD;j){intnumrandom.nextInt(10000);numbers.add(num);// 并发添加if(j%1000){// 偶尔删除Integerfirstnumbers.pollFirst();if(first!null){// 处理删除的元素}}}});threads.add(producer);}// 创建消费者线程只读for(inti0;iTHREAD_COUNT/2;i){ThreadconsumernewThread(()-{for(intj0;jOPERATIONS_PER_THREAD;j){// 并发遍历安全for(Integernum:numbers){// 处理元素}// 范围查询SetIntegersubsetnumbers.subSet(1000,2000);// 处理子集}});threads.add(consumer);}// 启动所有线程threads.forEach(Thread::start);// 等待所有线程完成for(Threadthread:threads){thread.join();}System.out.println(最终集合大小: numbers.size());System.out.println(最小值: numbers.first());System.out.println(最大值: numbers.last());}}导航和范围查询ConcurrentSkipListSetIntegersetnewConcurrentSkipListSet();for(inti1;i100;i){set.add(i);}// 1. 导航方法线程安全Integerlowerset.lower(50);// 49小于50的最大元素Integerfloorset.floor(50);// 50小于等于50的最大元素Integerhigherset.higher(50);// 51大于50的最小元素Integerceilingset.ceiling(50);// 50大于等于50的最小元素// 2. 弹出首尾元素线程安全Integerfirstset.pollFirst();// 1并从集合移除Integerlastset.pollLast();// 100并从集合移除// 3. 子集操作返回视图支持并发修改ConcurrentNavigableSetIntegerheadSetset.headSet(50);// [2..49]ConcurrentNavigableSetIntegertailSetset.tailSet(51);// [51..99]ConcurrentNavigableSetIntegersubSetset.subSet(20,80);// [20..79]// 4. 包含边界的子集ConcurrentNavigableSetIntegerinclusiveSubSetset.subSet(20,true,80,true);// [20..80]// 5. 逆序视图ConcurrentNavigableSetIntegerdescendingSetset.descendingSet();// 逆序遍历IteratorIntegerdescendingIteratorset.descendingIterator();5、CopyOnWriteArraySetCopyOnWriteArraySet是基于CopyOnWriteArrayList实现的线程安全的 Set采用“写时复制”策略适合读多写少的并发场景。底层实现原理publicclassCopyOnWriteArraySetEextendsAbstractSetEimplementsjava.io.Serializable{// 底层使用 CopyOnWriteArrayListprivatefinalCopyOnWriteArrayListEal;// 构造方法publicCopyOnWriteArraySet(){alnewCopyOnWriteArrayListE();}publicCopyOnWriteArraySet(Collection?extendsEc){// 使用CopyOnWriteArrayList的去重构造alnewCopyOnWriteArrayListE();al.addAllAbsent(c);// 只添加不存在的元素}}核心特性特性CopyOnWriteArraySetHashSetConcurrentSkipListSet底层结构动态数组哈希表跳表线程安全✅ 是❌ 否✅ 是写时复制✅ 是❌ 否❌ 否有序性插入顺序无序自然排序允许null✅ 允许✅ 允许❌ 不允许迭代器快照迭代器快速失败弱一致迭代器读性能✅ 极快无锁✅ 快✅ 快写性能❌ 慢复制数组✅ 快✅ 较快内存开销高低中等构造方法// 1. 默认构造空集合CopyOnWriteArraySetStringset1newCopyOnWriteArraySet();// 2. 从集合构造自动去重ListStringlistArrays.asList(A,B,A,C);CopyOnWriteArraySetStringset2newCopyOnWriteArraySet(list);// 结果[A, B, C]保持第一次出现的顺序// 3. 从数组构造需要先转为集合String[]array{X,Y,X,Z};CopyOnWriteArraySetStringset3newCopyOnWriteArraySet(Arrays.asList(array));// 4. 从其他Set构造保持原Set特性SetStringhashSetnewHashSet(Arrays.asList(A,B,C));CopyOnWriteArraySetStringset4newCopyOnWriteArraySet(hashSet);添加元素// CopyOnWriteArraySet的add方法publicbooleanadd(Ee){returnal.addIfAbsent(e);// 关键保证元素唯一}// CopyOnWriteArrayList的addIfAbsent实现publicbooleanaddIfAbsent(Ee){Object[]snapshotgetArray();// 检查是否已存在if(indexOf(e,snapshot,0,snapshot.length)0){returnfalse;}// 不存在创建新数组并添加returnaddIfAbsent(e,snapshot);}privatebooleanaddIfAbsent(Ee,Object[]snapshot){synchronized(lock){Object[]currentgetArray();intlencurrent.length;// 再次检查双重检查锁定模式if(snapshot!current){intcommonMath.min(snapshot.length,len);for(inti0;icommon;i){if(current[i]!snapshot[i]eq(e,current[i])){returnfalse;}}if(indexOf(e,current,common,len)0){returnfalse;}}// 创建新数组并添加元素Object[]newElementsArrays.copyOf(current,len1);newElements[len]e;setArray(newElements);returntrue;}}查找元素// contains方法无锁读取publicbooleancontains(Objecto){returnal.contains(o);// 直接读取当前数组}// CopyOnWriteArrayList.contains实现publicbooleancontains(Objecto){Object[]elementsgetArray();returnindexOf(o,elements,0,elements.length)0;}迭代器// 返回快照迭代器publicIteratorEiterator(){returnal.iterator();// 基于创建时的数组快照}// CopyOnWriteArrayList.iterator实现publicIteratorEiterator(){returnnewCOWIteratorE(getArray(),0);}staticfinalclassCOWIteratorEimplementsListIteratorE{privatefinalObject[]snapshot;privateintcursor;COWIterator(Object[]elements,intinitialCursor){cursorinitialCursor;snapshotelements;// 保存数组快照}publicbooleanhasNext(){returncursorsnapshot.length;}publicEnext(){if(!hasNext())thrownewNoSuchElementException();return(E)snapshot[cursor];}// 不支持修改操作publicvoidremove(){thrownewUnsupportedOperationException();}}基本操作// 创建CopyOnWriteArraySetCopyOnWriteArraySetStringuserSetnewCopyOnWriteArraySet();// 1. 添加元素线程安全userSet.add(Alice);userSet.add(Bob);userSet.add(Alice);// 重复不会添加userSet.add(null);// 允许nullSystem.out.println(userSet);// [Alice, Bob, null]// 2. 并发读取无需加锁booleanhasAliceuserSet.contains(Alice);// true无锁读取intsizeuserSet.size();// 3无锁读取// 3. 安全遍历for(Stringuser:userSet){System.out.println(user);// 不会抛出ConcurrentModificationException}// 4. 删除元素booleanremoveduserSet.remove(Bob);// trueuserSet.remove(null);// 删除null元素// 5. 批量操作userSet.addAll(Arrays.asList(Charlie,David,Eve));userSet.removeAll(Arrays.asList(Alice,Charlie));System.out.println(最终集合: userSet);// [David, Eve]集合运算CopyOnWriteArraySetIntegersetAnewCopyOnWriteArraySet(Arrays.asList(1,2,3,4,5));CopyOnWriteArraySetIntegersetBnewCopyOnWriteArraySet(Arrays.asList(4,5,6,7,8));// 1. 并集线程安全CopyOnWriteArraySetIntegerunionnewCopyOnWriteArraySet(setA);union.addAll(setB);System.out.println(并集: union);// [1, 2, 3, 4, 5, 6, 7, 8]// 2. 交集CopyOnWriteArraySetIntegerintersectionnewCopyOnWriteArraySet(setA);intersection.retainAll(setB);System.out.println(交集: intersection);// [4, 5]// 3. 差集CopyOnWriteArraySetIntegerdifferencenewCopyOnWriteArraySet(setA);difference.removeAll(setB);System.out.println(差集(A-B): difference);// [1, 2, 3]// 4. 对称差集CopyOnWriteArraySetIntegersymmetricDiffnewCopyOnWriteArraySet(union);symmetricDiff.removeAll(intersection);System.out.println(对称差集: symmetricDiff);// [1, 2, 3, 6, 7, 8]