Skip to content

集合概述与体系

概述

Java 集合框架(Java Collections Framework,JCF)是 JDK 提供的一组容器 API,用于存储和操作一组对象。与数组相比,集合的长度可变、支持丰富的增删改查操作,并且针对不同使用场景提供了多种实现(如有序/无序、允许重复/不允许重复、基于哈希/基于树等)。日常开发中,集合是使用频率极高的基础 API,位于 java.util 包中。

前置建议

已掌握 数组泛型基础。集合中大量使用泛型(如 List<String>Map<K,V>),先学泛型再学集合会更顺畅。


为什么需要集合

数组长度固定,且只支持按索引访问,无法方便地表示「一组会动态增删的元素」或「键值对」等结构。集合框架提供了:

  • 可变长度:按需增删元素,无需事先定长。
  • 多种结构:列表(有序可重复)、集合(不重复)、键值对(Map)等。
  • 统一接口:通过 ListSetMap 等接口编程,可随时更换实现类而不影响业务逻辑。
  • 泛型支持List<String>Map<Integer, String> 等,类型安全、无需强转。

集合体系结构

Java 集合框架以接口为主、实现类为辅。顶层可划分为两大分支:

  1. Collection — 单列集合,存储一组元素(每个元素一个对象)。
  2. Map — 双列集合,存储键值对(key-value),每个元素由键与值组成。

Collection 分支

Collection 是 List、Set、Queue 的父接口,表示「一组对象的容器」。常用子接口与实现类关系可简化为:

接口含义常用实现类典型特点
List有序、可重复ArrayListLinkedList有下标,可重复,ArrayList 查询快、LinkedList 头尾增删方便
Set不重复HashSetLinkedHashSetTreeSet无重复;HashSet 无序,TreeSet 可排序,LinkedHashSet 保持插入顺序
Queue队列LinkedListArrayDequePriorityQueue先进先出或优先级队列;List/Set/Map 的详细用法见 List、Set、Map 详解

记忆要点

  • List:像「动态数组」,有顺序、可重复,按索引访问。
  • Set:像「数学集合」,不重复;具体是否有序、是否可排序看实现类。
  • Map:键值对,键不重复,一个键对应一个值。

Map 分支

Map 不继承 Collection,表示「键 → 值」的映射。常用实现类:

实现类典型特点
HashMap无序(不保证顺序),键不重复,查询/增删平均 O(1)
LinkedHashMap在 HashMap 基础上保持插入顺序(或访问顺序)
TreeMap键按自然顺序或自定义比较器排序

体系关系简图

                    Iterable
                        |
                   Collection
                   /   |   \
                 List Set  Queue
                  |    |      |
            ArrayList HashSet LinkedList / ArrayDeque / ...
             LinkedList LinkedHashSet
                   TreeSet

  Map (独立分支)
    |
  HashMap / LinkedHashMap / TreeMap

实际编码时,我们通常面向接口声明变量(如 List<String> list),再在创建时选择具体实现(如 new ArrayList<>()),这样后续若要换成 LinkedList 只需改一行构造代码。


基本示例

示例 1:List —— 有序可重复

java
import java.util.ArrayList;
import java.util.List;

// 面向接口声明,用 ArrayList 实现
List<String> list = new ArrayList<>();
list.add("苹果");
list.add("香蕉");
list.add("苹果");           // 允许重复
System.out.println(list);   // [苹果, 香蕉, 苹果]
System.out.println(list.get(1));  // 香蕉,按索引访问

示例 2:Set —— 不重复

java
import java.util.HashSet;
import java.util.Set;

Set<String> set = new HashSet<>();
set.add("苹果");
set.add("香蕉");
set.add("苹果");            // 重复元素不会多存一份
System.out.println(set);    // [苹果, 香蕉](顺序不保证)

示例 3:Map —— 键值对

java
import java.util.HashMap;
import java.util.Map;

Map<String, Integer> map = new HashMap<>();
map.put("语文", 90);
map.put("数学", 85);
map.put("语文", 88);       // 同一键会覆盖原值
System.out.println(map.get("语文"));  // 88
System.out.println(map);   // {语文=88, 数学=85}(顺序不保证)

如何选择集合类型

  • 需要有序、可重复、按索引访问 → 用 List,一般选 ArrayList;若频繁在头尾增删,考虑 LinkedList
  • 需要不重复、不关心顺序 → Set,常用 HashSet;需要插入顺序LinkedHashSet,需要排序TreeSet
  • 需要键值对、按键找值 → Map,常用 HashMap;需要键有序TreeMap,需要插入顺序LinkedHashMap

注意

上述常用实现类(如 ArrayListHashSetHashMap)都是非线程安全的。多线程并发读写同一集合时,应使用并发包中的实现(如 ConcurrentHashMap)或通过同步手段保护,详见 并发


注意事项

  1. 使用泛型:强烈建议使用 List<String>Set<Integer>Map<K,V> 等形式,避免使用原始类型 ListMap,以在编译期获得类型检查,详见 泛型在集合中的使用
  2. null 与实现类ArrayListHashSetHashMap 允许元素或键为 null(HashMap 键仅允许一个 null);TreeSetTreeMap 的键不能为 null,否则会抛 NullPointerException
  3. equals 与 hashCode:若将自定义类作为 Set 的元素或 Map 的键,必须正确重写 equalshashCode,否则重复判定和哈希行为会异常,参见 常用类(Object/equals-hashCode)

相关链接

基于 VitePress 构建