Java 集合框架深度解析

Java 集合框架(Java Collections Framework, JCF)是 Java 语言的核心组成部分,提供了一套高效、灵活的数据结构和算法实现。它是处理对象集合的标准架构,广泛应用于各种 Java 开发场景。

一、集合框架体系结构

graph TD
    Collection[Collection接口] --> List[List接口]
    Collection --> Set[Set接口]
    Collection --> Queue[Queue接口]
    Map[Map接口]
    
    List --> ArrayList
    List --> LinkedList
    List --> Vector
    Vector --> Stack
    
    Set --> HashSet
    Set --> TreeSet
    Set --> LinkedHashSet
    
    Queue --> PriorityQueue
    Queue --> LinkedList
    Queue --> ArrayDeque
    
    Map --> HashMap
    Map --> TreeMap
    Map --> LinkedHashMap
    Map --> Hashtable

二、核心接口详解

1. Collection 接口

  • 所有集合类的根接口
  • 主要方法:
    • add(E e):添加元素
    • remove(Object o):删除元素
    • size():返回元素数量
    • iterator():返回迭代器
    • contains(Object o):检查包含元素

2. List 接口(有序集合)

  • 特点:元素有序、可重复、可通过索引访问
  • 实现类:
    • ​ArrayList​​:基于动态数组,随机访问快(O(1)),插入删除慢(O(n))
    • ​LinkedList​​:基于双向链表,插入删除快(O(1)),随机访问慢(O(n))
    • ​Vector​​:线程安全版 ArrayList(已过时)
    • ​Stack​​:后进先出(LIFO)结构

3. Set 接口(无序集合)

  • 特点:元素唯一、无序
  • 实现类:
    • ​HashSet​​:基于哈希表,最快查找(O(1)),无序
    • ​LinkedHashSet​​:保持插入顺序的 HashSet
    • ​TreeSet​​:基于红黑树,元素有序(O(log n))

4. Queue 接口(队列)

  • 特点:先进先出(FIFO)或优先级队列
  • 实现类:
    • ​LinkedList​​:可用作队列
    • ​PriorityQueue​​:优先级队列
    • ​ArrayDeque​​:双端队列

5. Map 接口(键值对)

  • 特点:键值对映射,键唯一
  • 实现类:
    • ​HashMap​​:基于哈希表,最快查找(O(1))
    • ​LinkedHashMap​​:保持插入顺序的 HashMap
    • ​TreeMap​​:基于红黑树,键有序(O(log n))
    • ​Hashtable​​:线程安全版 HashMap(已过时)

三、核心实现类对比

List 实现类对比

​特性​ ArrayList LinkedList Vector
底层结构 动态数组 双向链表 动态数组
随机访问性能 O(1) 极快 O(n) 慢 O(1)
插入/删除性能 O(n) 慢 O(1) 极快 O(n)
内存占用 较小 较大(节点指针) 较小
线程安全 是(已过时)
扩容机制 1.5倍 2倍

Set 实现类对比

​特性​ HashSet LinkedHashSet TreeSet
底层实现 HashMap LinkedHashMap TreeMap
元素顺序 无序 插入顺序 自然/比较器顺序
性能(O(1)) 否(O(log n))
允许null元素 否(需比较)
线程安全

Map 实现类对比

​特性​ HashMap LinkedHashMap TreeMap ConcurrentHashMap
底层结构 数组+链表/红黑树 链表+哈希表 红黑树 分段锁+哈希表
元素顺序 无序 插入/访问顺序 键排序 无序
性能(O(1)) 否(O(log n))
允许null键/值 是/是 是/是 否/是 否/否
线程安全

四、集合框架核心算法

1. 排序算法

// List排序
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
Collections.sort(numbers); // 升序排序
Collections.sort(numbers, Collections.reverseOrder()); // 降序排序

// Set排序(使用TreeSet)
Set<Integer> sortedSet = new TreeSet<>(numbers);

// Map按键排序
Map<String, Integer> map = new HashMap<>();
Map<String, Integer> sortedMap = new TreeMap<>(map);

2. 查找算法

// 二分查找(需先排序)
int index = Collections.binarySearch(numbers, 4);

// 集合查找
boolean contains = numbers.contains(5);

3. 洗牌算法

Collections.shuffle(numbers); // 随机打乱顺序

五、并发集合(java.util.concurrent)

1. CopyOnWriteArrayList

  • 写时复制技术
  • 读操作无锁,写操作复制整个数组
  • 适用读多写少场景

2. CopyOnWriteArraySet

  • 基于CopyOnWriteArrayList实现
  • 保证元素唯一性

3. ConcurrentHashMap

  • 分段锁技术(JDK7)
  • CAS+synchronized(JDK8+)
  • 高并发性能优异

4. BlockingQueue

  • 阻塞队列接口
  • 实现类:
    • ​ArrayBlockingQueue​​:数组实现的有界队列
    • ​LinkedBlockingQueue​​:链表实现的可选有界队列
    • ​PriorityBlockingQueue​​:优先级阻塞队列
    • ​SynchronousQueue​​:不存储元素的队列

六、集合最佳实践

1. 集合初始化

// 指定初始容量(避免频繁扩容)
List<String> list = new ArrayList<>(1000);

// 使用工厂方法(Java9+)
List<String> immutableList = List.of("A", "B", "C");
Set<Integer> immutableSet = Set.of(1, 2, 3);
Map<String, Integer> immutableMap = Map.of("A", 1, "B", 2);

2. 迭代器使用

// 安全删除元素
Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
    if (it.next() % 2 == 0) {
        it.remove(); // 安全删除
    }
}

// forEach遍历(Java8+)
numbers.forEach(System.out::println);

// 流式处理(Java8+)
numbers.stream()
       .filter(n -> n > 5)
       .map(n -> n * 2)
       .forEach(System.out::println);

3. 性能优化

  • ​ArrayList​​:预分配足够容量
  • ​HashMap​​:设置合理初始容量和负载因子
  • ​LinkedList​​:避免随机访问
  • ​TreeSet/TreeMap​​:提供高效Comparator

4. 线程安全策略

  • ​只读集合​​:使用不可变集合
  • ​低竞争场景​​:Collections.synchronizedXXX()
  • ​高并发场景​​:java.util.concurrent 包集合
  • ​写时复制​​:CopyOnWriteArrayList/CopyOnWriteArraySet

七、Java 8+ 新特性

1. Stream API

List<String> filtered = list.stream()
    .filter(s -> s.startsWith("A"))
    .map(String::toUpperCase)
    .collect(Collectors.toList());

2. Lambda表达式

Collections.sort(people, (p1, p2) -> 
    p1.getLastName().compareTo(p2.getLastName()));

3. 方法引用

names.forEach(System.out::println);

4. 新集合方法

map.computeIfAbsent("key", k -> new ArrayList<>()).add("value");
map.getOrDefault("key", Collections.emptyList());

八、集合框架设计模式

1. 迭代器模式

  • 提供统一遍历接口
  • 实现类:Iterator/ListIterator

2. 工厂模式

  • 集合工厂方法:List.of(), Set.of(), Map.of()

3. 适配器模式

  • Arrays.asList():数组转List适配器

4. 组合模式

  • Collections.unmodifiableXXX():创建不可变视图

九、常见问题与解决方案

1. ConcurrentModificationException

  • ​原因​​:迭代过程中修改集合
  • ​解决​​:
    • 使用迭代器的remove方法
    • 使用CopyOnWriteArrayList
    • 先收集要删除的元素,最后统一删除

2. 选择合适的集合

​场景​ ​推荐集合​
快速随机访问 ArrayList
频繁插入删除 LinkedList
元素唯一 HashSet
保持插入顺序 LinkedHashSet
元素排序 TreeSet
键值对存储 HashMap
保持键插入顺序 LinkedHashMap
键排序 TreeMap
高并发环境 ConcurrentHashMap
生产者-消费者模式 BlockingQueue

3. 正确实现 hashCode() 和 equals()

  • HashMap/HashSet 依赖这两个方法
  • 必须同时重写,且满足:
    • 相等对象必须有相同hashCode
    • hashCode相同对象不一定相等

十、性能调优指南

1. ArrayList 调优

  • 预分配容量:new ArrayList<>(initialCapacity)
  • 避免中间插入:使用add(index, element)代价高
  • 批量操作:使用addAll()代替循环add

2. HashMap 调优

  • 设置初始容量:new HashMap<>(initialCapacity)
  • 设置负载因子:new HashMap<>(16, 0.75f)
  • 使用String.intern()作为键减少内存

3. 集合选择策略

graph TD
    A[需要存储键值对?] -->|是| B[需要排序?]
    A -->|否| C[需要元素唯一?]
    B -->|是| D[TreeMap]
    B -->|否| E[HashMap或LinkedHashMap]
    C -->|是| F[HashSet或TreeSet]
    C -->|否| G[ArrayList或LinkedList]
    G --> H[需要频繁插入删除?]
    H -->|是| I[LinkedList]
    H -->|否| J[ArrayList]

Java 集合框架是 Java 开发者必须掌握的核心技能之一。合理选择和使用集合类,能够显著提高程序性能和代码质量。深入理解各集合类的实现原理和适用场景,是编写高效 Java 程序的关键。

更多推荐