Java集合(Collection、Map、转换)

✅ 推荐使用

❌ 已过时

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
  1. Collection:用于存储单列元素集合(如 List、Set、Queue 等),每个元素是独立的。
  2. 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 String0)
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());
相关推荐
xcl09255 小时前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐7 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长7 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn7 小时前
Spring 注解使用详解
java·spring
一条小小yu7 小时前
Spring IoC的理解
java·后端·spring
落魄实习生8 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈8 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白9 小时前
核心功能(Service接口)
java·mybatis
乌暮10 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习