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 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());
相关推荐
jingfeng5141 小时前
C++模板进阶
java·c++·算法
杨杨杨大侠2 小时前
附录 1:[特殊字符] Maven Central 发布完整指南:从零到成功部署
java·spring boot·maven
ahauedu2 小时前
AI资深 Java 研发专家系统解析Java 中常见的 Queue实现类
java·开发语言·中间件
小厂永远得不到的男人2 小时前
基于 Spring Validation 实现全局参数校验异常处理
java·后端·架构
计算机编程小咖3 小时前
《基于大数据的农产品交易数据分析与可视化系统》选题不当,毕业答辩可能直接挂科
java·大数据·hadoop·python·数据挖掘·数据分析·spark
艾莉丝努力练剑3 小时前
【C语言16天强化训练】从基础入门到进阶:Day 7
java·c语言·学习·算法
老华带你飞3 小时前
校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园交友网站
自强的小白4 小时前
学习Java24天
java·学习
Ashlee_code5 小时前
香港券商櫃台系統跨境金融研究
java·python·科技·金融·架构·系统架构·区块链