✅ 推荐使用
❌ 已过时
1. Collection
Collection 是集合框架的根接口之一,它是所有单列集合(如 List、Set、Queue 等)的公共父接口。Collection 接口定义了集合的基本操作,比如添加、删除、遍历等。
Collection
├── List
│ ├── ArrayList
│ ├── LinkedList
│ └── Vector
│ └── Stack
├── Set
│ ├── HashSet
│ │ └── LinkedHashSet
│ └── TreeSet (SortedSet → NavigableSet)
└── Queue
├── PriorityQueue
└── Deque
├── LinkedList
└── ArrayDeque
- Set
- List
- Queue: 队列
- Deque: 双端队列
- PriorityQueue: 优先队列
- ❌ Stack: 栈(已过时)
- Vector: 旧版线程安全 List
Collection 常用方法
- boolean add(E e): 添加元素。
- boolean remove(Object o): 移除指定元素。
- boolean contains(Object o): 是否包含指定元素。
- int size(): 返回集合大小。
- boolean isEmpty(): 判断集合是否为空。
- Iterator iterator(): 返回迭代器。
- Object[] toArray(): 转换为数组。
- boolean containsAll(Collection<?> c): 是否包含另一个集合的所有元素。
- boolean addAll(Collection<? extends E> c): 添加另一个集合的所有元素。
- boolean removeAll(Collection<?> c): 移除与另一个集合共有的元素。
- void clear(): 清空集合。
Collection 子接口
- List: 有序、可重复。
- Set: 无序、不可重复。
- Queue: 队列,先进先出。
- Deque: 双端队列。
Collection 实现类(推荐使用的)
- ✅ ArrayList: 快速随机访问。
- ✅ LinkedList: 频繁插入/删除。
- ✅ HashSet: 去重元素。
- ✅ LinkedHashSet: 保持插入顺序的去重集合。
- ✅ TreeSet: 需要排序的集合。
- ✅ PriorityQueue: 优先级队列。
- ✅ Collections.synchronizedCollection() 或 CopyOnWriteArrayList: 高并发线程安全集合。
1.1 Set
Set 是一个不允许重复元素的集合接口,继承自 Collection 接口。
- ✅ HashSet: 效率O(1);基于HashMap实现,使用哈希表。
- ✅ LinkedHashSet: 效率O(1);继承自 HashSet,内部使用双向链表维护插入顺序。
- ✅ TreeSet: 效率O(log n);基于红黑树实现,支持排序。
- ConcurrentSkipListSet: 效率O(log n);支持并发访问的有序 Set,基于跳表实现。
- ❌ Collections.synchronizedSet(new HashSet<>()): 效率O(1);通过装饰器模式使任意 Set 线程安全,但效率较低。
线程安全
- ConcurrentSkipListSet
- Collections.synchronizedSet(new HashSet<>())
有序的
- LinkedHashSet
- TreeSet
- ConcurrentSkipListSet
✅ HashSet
特点:基于哈希表,查找和插入效率高(O(1)),但不保证顺序。
适用场景:需要快速查找、去重,对顺序无要求。
java
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("A"); // 重复元素不会被添加
System.out.println(set); // 输出顺序不确定
✅ LinkedHashSet
特点:保留插入顺序,性能略低于 HashSet。
适用场景:需要去重同时保持插入顺序。
java
Set<String> set = new LinkedHashSet<>();
set.add("C");
set.add("A");
set.add("B");
System.out.println(set); // 输出顺序:C, A, B
✅ TreeSet
特点:自动排序(默认自然排序或自定义比较器),不允许 null。
适用场景:需要排序或范围查询的场景。
java
Set<String> set = new TreeSet<>();
set.add("Banana");
set.add("Apple");
set.add("Orange");
System.out.println(set); // 输出按字母顺序排序
ConcurrentSkipListSet
特点:线程安全、有序、基于跳表实现。
适用场景:多线程环境下需要有序 Set 的场景。
java
Set<String> set = new ConcurrentSkipListSet<>();
set.add("Z");
set.add("X");
set.add("Y");
System.out.println(set); // 按排序顺序输出
1.2 List
List 是一个有序、可重复的集合接口,继承自 Collection 接口。
- ✅ ArrayList: 效率O(n);快速随机访问、读多写少。
- ✅ LinkedList: 效率O(1);频繁插入/删除。
- Vector: 效率O(n);旧版线程安全列表。
- CopyOnWriteArrayList: 效率O(n);高并发读多写少。
- Collections.synchronizedList(new ArrayList<>()): 效率O(n);手动同步任意 List。
线程安全
- Vector
- CopyOnWriteArrayList
- Collections.synchronizedList(new ArrayList<>())
基于数组
- ArrayList
- Vector
- CopyOnWriteArrayList
- Collections.synchronizedList(new ArrayList<>())
支持快速随机访问
- ArrayList
- Vector
- CopyOnWriteArrayList
- Collections.synchronizedList(new ArrayList<>())
✅ ArrayList
特点:基于动态数组实现,支持快速随机访问(O(1)),插入/删除中间元素效率较低(O(n))。
适用场景:读操作频繁、写操作较少。
java
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
System.out.println(list.get(0)); // 快速访问
✅ LinkedList
特点:基于双向链表实现,插入/删除效率高(特别是头部/尾部),但随机访问慢(O(n))。
适用场景:频繁插入/删除、不频繁随机访问。
java
List<String> list = new LinkedList<>();
list.add("X");
list.add("Y");
((LinkedList<String>) list).addFirst("Z"); // 插入头部
System.out.println(list);
❌ Vector
特点:与 ArrayList 类似,但所有方法都是 synchronized,线程安全但性能较差。
适用场景:遗留系统中使用,现代推荐使用 CopyOnWriteArrayList 或手动同步。
java
List<String> list = new Vector<>();
list.add("Apple");
list.add("Banana");
System.out.println(list);
CopyOnWriteArrayList
特点:线程安全,写时复制(Copy-On-Write)机制,读不加锁,适合读多写少的并发场景。
适用场景:监听器列表、事件广播等并发读多写少的场景。
java
// java.util.concurrent.CopyOnWriteArrayList;
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("Read1");
list.add("Read2");
new Thread(() -> {
list.add("Write1"); // 写操作会复制数组
}).start();
Collections.synchronizedList
特点:通过装饰器模式使任意 List 线程安全,适合低并发场景。
缺点:性能较差,不适用于高并发。
java
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
syncList.add("A");
1.3 Query
Queue(队列) 是 Collection 接口的一个子接口,用于表示先进先出(FIFO)的数据结构。它广泛用于任务调度、消息队列、线程池等场景。
- LinkedList: 实现了 Deque,可作双端队列。
- ✅ ArrayDeque: 性能优于 LinkedList,推荐作队列。
- PriorityQueue: 元素必须可排序(实现 Comparable 或提供 Comparator)。
- ✅ ConcurrentLinkedQueue: 线程安全、非阻塞,适合高并发。
- ✅ LinkedBlockingQueue: 可指定容量,适合生产者-消费者模型。
- ArrayBlockingQueue: 基于数组实现,性能稳定。
- PriorityBlockingQueue: 线程安全的优先级队列。
- DelayQueue: 元素需实现 Delayed 接口,适合定时任务。
- SynchronousQueue: 每次插入必须等待取出,适合线程协作。
线程安全
- ✅ ConcurrentLinkedQueue
- ✅ LinkedBlockingQueue
- ArrayBlockingQueue
- PriorityBlockingQueue
- DelayQueue
- SynchronousQueue
1.4 Deque
Deque(Double-ended Queue,双端队列) 是 Queue 接口的子接口,允许从两端插入、删除和检查元素。它既可以作为队列(FIFO),也可以作为栈(LIFO)使用。
- ✅ ArrayDeque: 高性能双端队列,推荐首选。
- LinkedList: 实现了 Deque 和 List,功能丰富。
- ConcurrentLinkedDeque: 线程安全的非阻塞双端队列。
- LinkedBlockingDeque: 线程安全、支持阻塞操作。
- ❌Stack(Vector 子类): 已过时,推荐使用 Deque 代替。
java
Deque<String> deque = new ArrayDeque<>();
deque.addFirst("B");
deque.addLast("C");
System.out.println(deque.removeFirst()); // 输出 B
线程安全
- ConcurrentLinkedDeque
- LinkedBlockingDeque
- ❌Stack
1.5 PriorityQueue
PriorityQueue 是一种基于堆(heap)结构实现的优先队列,它允许你以优先级顺序取出元素(默认是自然顺序,也可以自定义排序)。它广泛用于任务调度、图算法(如 Dijkstra)、K-Top 问题等场景。
- PriorityQueue: Java 标准库实现,基于堆结构。
- ✅ PriorityBlockingQueue: 线程安全的优先队列,适合并发环境。
- TreeSet(伪优先队列): 本质是集合,但可实现排序,效率不如 PriorityQueue。
- ConcurrentSkipListSet: 线程安全的有序集合,性能略逊于 PriorityBlockingQueue。
java
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(3);
pq.offer(1);
pq.offer(2);
System.out.println(pq.poll()); // 输出 1
线程安全
- ✅ PriorityBlockingQueue
- ConcurrentSkipListSet
2. Map
Map 并不属于 Collection 接口的子接口或实现类。虽然 Map 和 Collection 都是 Java 集合框架的重要组成部分,但它们是两个并列的接口,分别用于表示不同类型的集合结构。
Map
├── HashMap
│ └── LinkedHashMap
├── TreeMap (SortedMap → NavigableMap)
├── Hashtable
│ └── Properties
└── ConcurrentHashMap
- Collection:用于存储单列元素集合(如 List、Set、Queue 等),每个元素是独立的。
- Map:用于存储双列数据(键值对),即 Key-Value 对,每个元素由一个键和一个值组成。
- ✅ HashMap: 效率O(1);基于哈希表实现。
- LinkedHashMap: 效率O(1);继承自 HashMap,维护插入或访问顺序。
- TreeMap: 效率O(n);基于红黑树实现,支持排序。
- ✅ ConcurrentHashMap: 效率O(1) ~ O(log n);线程安全,高并发推荐(替代 Collections.synchronizedMap())。
- Hashtable: 效率O(1);旧版线程安全 Map。
- Properties: 属性集合
- Collections.synchronizedMap(new HashMap<>()): 效率O(1);通过装饰器模式使任意 Map 线程安全。
线程安全
- ConcurrentHashMap
- Hashtable
- Collections.synchronizedMap(new HashMap<>())
有序的
- LinkedHashMap
- TreeMap
2.1 ✅ HashMap
特点:基于哈希表,查找和插入效率高(O(1)),不保证顺序。
适用场景:需要快速查找、去重键,对顺序无要求。
java
Map<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
System.out.println(map.get("A")); // 输出 1
2.2 LinkedHashMap
特点:保留插入顺序或访问顺序(可配置),性能略低于 HashMap。
适用场景:需要缓存、保持插入顺序或 LRU 缓存。
java
Map<String, Integer> map = new LinkedHashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
System.out.println(map); // 输出 {A=1, B=2, C=3}(保持插入顺序)
2.3 TreeMap
特点:自动排序(默认自然排序或自定义比较器),不允许 null 键。
适用场景:需要排序或范围查询的场景。
java
Map<String, Integer> map = new TreeMap<>();
map.put("B", 2);
map.put("A", 1);
map.put("C", 3);
System.out.println(map); // 输出 {A=1, B=2, C=3}(按键排序)
2.4 ✅ ConcurrentHashMap
特点:线程安全,支持高并发读写操作,不加锁读取。
适用场景:多线程环境下需要高性能的 Map。
java
// java.util.concurrent.ConcurrentHashMap
Map<String, Integer> map = new ConcurrentHashMap<>();
map.put("A", 1);
map.put("B", 2);
System.out.println(map.get("A")); // 输出 1
2.5 Collections.synchronizedMap
特点:通过装饰器使任意 Map 线程安全,适合低并发场景。
缺点:性能差,不适用于高并发。
java
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
syncMap.put("A", 1);
2.6 Properties(Hashtable子类)
Properties 是 Hashtable 的子类,用于表示键值对(key-value)形式的配置信息,常用于读取配置文件(如 .properties 文件)或保存系统属性。
- Properties: Java 标准库实现,线程安全,支持从流中加载和写入。
- System.getProperties(): 获取 JVM 的系统属性,本质是 Properties 实例。
- PropertyResourceBundle: 用于国际化资源文件加载,基于 .properties 文件。
- Preferences: 轻量级持久化存储,基于注册表或 XML,适合用户偏好设置。
线程安全
- Properties
- System.getProperties()
- PropertyResourceBundle
- Preferences
3. AbstractSet
AbstractSet 是 Java 集合框架中 Set 接口的一个抽象实现类,它继承自 AbstractCollection,并实现了 Set 接口。
3.1 EnumSet
EnumSet 是一个抽象类,Java 提供了两种高效实现:
- ✅ RegularEnumSet: 使用 long 类型位掩码存储,最多支持 64 个枚举常量
- JumboEnumSet: 使用 long[] 数组存储,支持超过 64 个枚举常量
java
enum Color { RED, GREEN, BLUE }
EnumSet<Color> set = EnumSet.of(Color.RED, Color.BLUE);
System.out.println(set); // 输出 [RED, BLUE]
线程安全
EnumSet 本身都不是线程安全的
- Collections.synchronizedSet()
4. AbstractMap
AbstractMap 是 Java 集合框架中 Map 接口的一个抽象实现类,它为 Map 提供了部分默认实现,使得开发者可以更方便地创建自定义的 Map 实现。
java.lang.Object
└── java.util.AbstractMap<K, V>
├── java.util.EnumMap<K extends Enum<K>, V>
├── java.util.HashMap<K, V>
├── java.util.TreeMap<K, V>
├── java.util.WeakHashMap<K, V>
└── java.util.IdentityHashMap<K, V>
- IdentityHashMap: 基于引用的 Map
- WeakHashMap: 弱引用 Map
- EnumMap: 高效处理枚举类型
4.1 EnumMap
EnumMap 是 Map 接口的一个高效实现,专门用于枚举类型作为键的情况:
- ✅ EnumMap: 枚举键映射
java
enum Color { RED, GREEN, BLUE }
EnumMap<Color, String> map = new EnumMap<>(Color.class);
map.put(Color.RED, "Red");
System.out.println(map.get(Color.RED)); // 输出 Red
线程安全
EnumMap 本身都不是线程安全的
- synchronizedMap()
- ConcurrentHashMap
4.2 IdentityHashMap
IdentityHashMap 是 Map 接口的一个特殊实现,它使用引用相等(==) 而不是对象相等(.equals())来比较键。这与标准的 HashMap 或 TreeMap 不同,后者默认使用 .equals() 和 hashCode() 来判断键是否相同。
- ✅ IdentityHashMap: Java 标准库实现,适用于键需严格引用相等的场景
- ConcurrentIdentityHashMap: 非官方类,需使用第三方库(如 Guava)
- WeakHashMap: 键使用弱引用,适合缓存,但不是 IdentityMap
java
IdentityHashMap<String, String> map = new IdentityHashMap<>();
String key1 = new String("key");
String key2 = new String("key");
map.put(key1, "value1");
map.put(key2, "value2");
System.out.println(map.get(key1)); // 输出 value1
线程安全
- ConcurrentIdentityHashMap
- WeakHashMap
4.3 WeakHashMap
WeakHashMap 是 Map 接口的一个特殊实现,它使用 弱引用(WeakReference) 来持有键(key),这意味着当键不再被强引用时,它将被垃圾回收器回收,同时从 WeakHashMap 中自动移除。
这种特性非常适合用于缓存、监听器注册、资源池等场景,避免内存泄漏。
- ✅ WeakHashMap: Java 标准库实现,键为弱引用
- WeakConcurrentHashMap: 线程安全的 WeakHashMap 替代
- SoftHashMap(非标准): 使用软引用(SoftReference),适合缓存
- PhantomHashMap(非标准): 使用虚引用(PhantomReference),极少使用
- ConcurrentWeakHashMap(Guava 等库): 第三方线程安全实现
java
WeakHashMap<String, String> map = new WeakHashMap<>();
String key = new String("key");
map.put(key, "value");
key = null; // key 变为不可达
System.gc(); // 建议回收
System.out.println(map); // 可能输出 {}
线程安全
- WeakConcurrentHashMap
- ConcurrentWeakHashMap(Guava 等库)
5. BitSet
BitSet 是用于操作位集合(bit vector)的一个类,继承自 Object 类,并没有实现任何接口(在 Java 7 及更早版本中),但从 Java 8 开始,实现了 Cloneable接口并支持 Serializable。
BitSet 是一种位数组,用于高效地表示一组布尔值(true/false、1/0)。比 boolean[] 存储效率高,可以动态扩容,支持与、或、异或等。
主要用途:
- 位标志存储:例如表示多个布尔选项。
- 集合操作:可以用来模拟整数集合的交、并、差等操作。
- 内存优化:相比使用 boolean[],BitSet 更节省空间。
- 快速查找和操作:适合处理大量布尔状态。
BitSet 的内部实现
BitSet 内部使用一个 long[] 数组来保存位数据:
java
private long[] words;
每个 long 是 64 位。
通过位运算(如 &, |, ~, <<, >>>)来操作每一位。
动态扩容:当设置的位超出当前数组大小时,自动扩展 words 数组。
java
BitSet bitSet = new BitSet();
// 设置位
bitSet.set(3); // 设置第3位为true
bitSet.set(5); // 设置第5位为true
System.out.println("BitSet: " + bitSet); // 输出: {3, 5}
// 查看某位是否为true
System.out.println("Is bit 3 set? " + bitSet.get(3)); // true
System.out.println("Is bit 4 set? " + bitSet.get(4)); // false
// 清除某位
bitSet.clear(3);
System.out.println("After clearing bit 3: " + bitSet); // {5}
// 位运算:与、或、异或等
BitSet bitSet2 = new BitSet();
bitSet2.set(5);
bitSet2.set(7);
bitSet.or(bitSet2); // 或操作
System.out.println("After OR with {5,7}: " + bitSet); // {5,7}
6. 转换
6.1 List → Set
- new HashSet<>(list)
java
List<String> list = Arrays.asList("a", "b", "a", "c");
Set<String> set = new HashSet<>(list);
System.out.println(set); // 输出 [a, b, c]
6.2 Set → List
- new ArrayList<>(set)
java
Set<String> set = new HashSet<>(Arrays.asList("x", "y", "z"));
List<String> list = new ArrayList<>(set);
System.out.println(list); // 输出 [x, y, z](顺序可能不同)
6.3 List/Set → Array
- list.toArray(new String[0])
java
List<String> list = Arrays.asList("apple", "banana", "cherry");
String[] array = list.toArray(new String[0]);
System.out.println(Arrays.toString(array)); // 输出 [apple, banana, cherry]
6.4 Array → List
- Arrays.asList(array):返回固定大小的 List,不支持增删操作(会抛出异常)
java
String[] array = {"red", "green", "blue"};
List<String> list = Arrays.asList(array); // 返回固定大小的 List,不支持增删操作(会抛出异常)
System.out.println(list); // 输出 [red, green, blue]
6.5 Map → Set
- map.entrySet()
java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
System.out.println(entrySet); // 输出 [a=1, b=2]
6.6 Set → Map
- 循环 put
java
Set<Map.Entry<String, Integer>> entrySet = new HashSet<>();
entrySet.add(new AbstractMap.SimpleEntry<>("x", 10));
entrySet.add(new AbstractMap.SimpleEntry<>("y", 20));
Map<String, Integer> map = new HashMap<>();
map.putAll(entrySet);
System.out.println(map); // 输出 {x=10, y=20}
6.7 List<Map.Entry> → Map
- list.stream().collect(Collectors.toMap())
java
List<Map.Entry<String, String>> list = new ArrayList<>();
list.add(new AbstractMap.SimpleEntry<>("key1", "value1"));
list.add(new AbstractMap.SimpleEntry<>("key2", "value2"));
Map<String, String> map = list.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(map); // 输出 {key1=value1, key2=value2}
6.8 Map → List(键或值)
- new ArrayList<>(map.keySet())
java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
List<String> keyList = new ArrayList<>(map.keySet());
List<Integer> valueList = new ArrayList<>(map.values());
List<Map.Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet());
System.out.println(keyList); // 输出 [a, b]
System.out.println(valueList); // 输出 [1, 2]
System.out.println(entryList); // 输出 [a=1, b=2]
6.9 Stream → 集合
- stream.collect(Collectors.toList())
java
Stream<String> stream = Stream.of("one", "two", "three");
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());