前言Java 集合框架Java Collections Framework是日常开发中使用频率最高的 API 之一但很多开发者只熟悉 ArrayList、HashMap 这几个常客对整个集合体系的全貌缺乏系统认知。本文将把 Java 集合框架中 所有常用和不常用的集合类 全部列举出来按体系结构分类介绍帮你建立一个完整的知识图谱。后续文章会对核心集合HashMap、ConcurrentHashMap、ArrayList、LinkedList进行源码级深入分析。本文基于 JDK 17部分内容会标注版本差异。一、集合框架的顶层接口Java 集合框架的设计以接口为核心所有集合类都实现了以下几个顶层接口之一Iterable └── Collection ├── List 有序、可重复 ├── Set 无序、不可重复 └── Queue/Deque 队列/双端队列 Map 键值对独立于 Collection 体系Collection 接口 是 List、Set、Queue 的父接口定义了集合的基本操作add()、remove()、contains()、size()、iterator()等。Map 接口 独立于 Collection 体系表示键值对映射关系定义了put()、get()、remove()、keySet()、values()、entrySet()等操作。二、List 家族有序可重复List 是最常用的集合类型元素有序按插入顺序且允许重复。2.1 ArrayList ⭐ListString list new ArrayList();底层结构Object[ ]数组默认容量10扩容时增长为原来的 1.5 倍oldCapacity (oldCapacity 1)特点随机访问快O(1)尾部插入快中间插入/删除慢需要移动元素线程安全否适用场景大多数需要 List 的场景读多写少2.2 LinkedList ⭐ListString list new LinkedList();底层结构双向链表同时实现了 List 和 Deque 接口特点中间插入/删除快O(1)但定位需要 O(n)随机访问慢O(n)线程安全否适用场景频繁在头尾操作的场景也可当作队列/栈使用2.3 VectorListString list new Vector();底层结构Object[ ]数组与 ArrayList 类似特点所有方法都加了synchronized线程安全但性能差扩容策略默认扩容为原来的 2 倍可通过构造函数指定增量现状已过时不推荐使用。需要线程安全的 List 请使用CopyOnWriteArrayList或Collections.synchronizedList()2.4 StackStackString stack new Stack();底层结构继承自 Vector特点后进先出LIFO提供push()、pop()、peek()方法现状已过时推荐使用ArrayDeque代替2.5 CopyOnWriteArrayListListString list new CopyOnWriteArrayList();底层结构Object[ ]数组每次写操作都会复制整个数组特点读操作无锁读取快照数组写操作加锁并复制底层数组线程安全是读写分离思想适用场景读远多于写的并发场景如监听器列表、配置缓存注意写操作代价高每次复制整个数组不适合频繁修改List 对比总结实现类底层结构随机访问插入/删除线程安全推荐度ArrayList数组O(1)O(n)否⭐⭐⭐LinkedList双向链表O(n)O(1)*否⭐⭐Vector数组O(1)O(n)是synchronized❌ 已过时Stack数组O(1)O(n)是synchronized❌ 已过时CopyOnWriteArrayList数组写时复制O(1)O(n)是COW⭐⭐*LinkedList 的 O(1) 插入是指在已定位的节点处操作通过索引定位仍需 O(n)。三、Map 家族键值对映射Map 是 Java 中最核心的数据结构之一存储键值对键不可重复。3.1 HashMap ⭐MapString, Object map new HashMap();底层结构数组 链表 红黑树JDK 8链表长度 ≥ 8 且数组长度 ≥ 64 时转红黑树默认容量16负载因子 0.75扩容为原来的 2 倍特点允许 null key 和 null value无序线程安全否适用场景大多数键值对存储场景3.2 LinkedHashMapMapString, Object map new LinkedHashMap();底层结构HashMap 双向链表维护插入顺序或访问顺序特点在 HashMap 的基础上通过双向链表维护元素的顺序排序模式插入顺序默认遍历时按 put 的先后顺序访问顺序设置accessOrdertrue每次 get/put 都会将该元素移到末尾经典应用实现 LRU 缓存重写removeEldestEntry()方法// LRU 缓存示例 MapString, Object lruCache new LinkedHashMap(16, 0.75f, true) { Override protected boolean removeEldestEntry(Map.EntryString, Object eldest) { return size() MAX_CACHE_SIZE; } };3.3 TreeMapMapString, Object map new TreeMap();底层结构红黑树特点Key 按自然顺序或自定义 Comparator 排序不允许 null key时间复杂度get/put/remove 均为 O(log n)适用场景需要按 Key 排序的场景如范围查询、排行榜独有方法firstKey()、lastKey()、subMap()、headMap()、tailMap()3.4 HashtableMapString, Object map new Hashtable();底层结构数组 链表特点所有方法加synchronized不允许 null key 和 null value现状已过时需要线程安全的 Map 请使用ConcurrentHashMap3.5 ConcurrentHashMap ⭐MapString, Object map new ConcurrentHashMap();底层结构JDK 7分段锁Segment 数组 HashEntry 数组 链表JDK 8数组 链表 红黑树与 HashMap 类似使用 CAS synchronized 保证并发安全特点高并发下性能远优于 Hashtable不允许 null key 和 null value线程安全是适用场景高并发读写的键值对存储3.6 ConcurrentSkipListMapMapString, Object map new ConcurrentSkipListMap();底层结构跳表Skip List特点线程安全的有序 Map相当于 TreeMap 的并发版本时间复杂度O(log n)适用场景需要并发安全 排序的场景3.7 WeakHashMapMapString, Object map new WeakHashMap();底层结构数组 链表与 HashMap 类似特点Key 使用弱引用WeakReference当 Key 没有强引用时GC 时会自动回收该键值对适用场景缓存场景如 ThreadLocalMap 的设计思想类似3.8 IdentityHashMapMapString, Object map new IdentityHashMap();底层结构数组key 和 value 交替存储特点使用而非equals()比较 Key两个内容相同但不是同一对象的 Key 被视为不同适用场景需要按对象引用而非内容做去重的场景如序列化框架、深拷贝检测循环引用3.9 EnumMapMapDayOfWeek, String map new EnumMap(DayOfWeek.class);底层结构数组按枚举的 ordinal 作为下标特点Key 必须是枚举类型内部用数组存储性能极高适用场景Key 为枚举类型时的最优选择3.10 PropertiesProperties props new Properties(); props.load(new FileInputStream(config.properties));底层结构继承自 Hashtable特点Key 和 Value 都是 String 类型支持从.properties文件加载/保存适用场景配置文件读取不过现在更多用 Spring 的 Value 或 ConfigurationPropertiesMap 对比总结实现类底层结构有序性线程安全null key推荐度HashMap数组链表红黑树无序否允许⭐⭐⭐LinkedHashMapHashMap双向链表插入/访问顺序否允许⭐⭐⭐TreeMap红黑树Key 排序否不允许⭐⭐Hashtable数组链表无序是不允许❌ 已过时ConcurrentHashMap数组链表红黑树无序是不允许⭐⭐⭐ConcurrentSkipListMap跳表Key 排序是不允许⭐⭐WeakHashMap数组链表无序否允许⭐IdentityHashMap数组无序否允许⭐EnumMap数组枚举顺序否不允许⭐⭐四、Set 家族不可重复Set 不允许存储重复元素大多数 Set 的实现底层都依赖对应的 Map。4.1 HashSetSetString set new HashSet();底层结构基于 HashMap 实现value 固定为一个PRESENT占位对象特点无序、不可重复允许一个 null 元素时间复杂度add/remove/contains 均为 O(1)适用场景去重、判断元素是否存在4.2 LinkedHashSetSetString set new LinkedHashSet();底层结构基于 LinkedHashMap 实现特点维护插入顺序的 HashSet适用场景需要去重 保持插入顺序4.3 TreeSetSetString set new TreeSet();底层结构基于 TreeMap 实现红黑树特点元素按自然顺序或自定义 Comparator 排序时间复杂度O(log n)适用场景需要有序的去重集合4.4 EnumSetSetDayOfWeek set EnumSet.of(DayOfWeek.MONDAY, DayOfWeek.FRIDAY);底层结构位向量bit vector用 long 类型的位运算实现特点专为枚举类型设计性能极高所有操作都是位运算实现类RegularEnumSet枚举值 ≤ 64 个用一个 long 存储JumboEnumSet枚举值 64 个用 long 数组存储适用场景枚举类型的集合操作4.5 CopyOnWriteArraySetSetString set new CopyOnWriteArraySet();底层结构基于 CopyOnWriteArrayList 实现特点线程安全每次写操作复制底层数组适用场景并发场景下元素较少的 Set4.6 ConcurrentSkipListSetSetString set new ConcurrentSkipListSet();底层结构基于 ConcurrentSkipListMap 实现特点线程安全的有序 Set相当于 TreeSet 的并发版本适用场景需要并发安全 排序的集合Set 对比总结实现类底层依赖有序性线程安全推荐度HashSetHashMap无序否⭐⭐⭐LinkedHashSetLinkedHashMap插入顺序否⭐⭐⭐TreeSetTreeMap排序否⭐⭐EnumSet位向量枚举顺序否⭐⭐CopyOnWriteArraySetCopyOnWriteArrayList插入顺序是⭐ConcurrentSkipListSetConcurrentSkipListMap排序是⭐⭐五、Queue / Deque 家族队列与双端队列5.1 普通队列ArrayDequeDequeString deque new ArrayDeque();底层结构循环数组特点既可以当队列FIFO也可以当栈LIFO性能优于 LinkedList 和 Stack默认容量16JDK 17 前/ 由初始元素数量决定JDK 17适用场景官方推荐的栈和队列实现替代 Stack 和 LinkedListPriorityQueueQueueInteger pq new PriorityQueue();底层结构最小堆数组实现的完全二叉树特点元素按优先级出队默认自然排序最小元素先出时间复杂度offer/poll 为 O(log n)peek 为 O(1)适用场景任务调度、Top K 问题、Dijkstra 算法LinkedList作为 Queue 使用QueueString queue new LinkedList();底层结构双向链表特点实现了 Deque 接口可以用作队列、双端队列、栈注意作为纯队列使用时ArrayDeque 性能更优5.2 阻塞队列BlockingQueue阻塞队列是并发编程的核心组件当队列为空时 take() 会阻塞当队列满时 put() 会阻塞。线程池 ThreadPoolExecutor 的核心依赖就是阻塞队列。ArrayBlockingQueueBlockingQueueString queue new ArrayBlockingQueue(100);底层结构定长数组 ReentrantLock 两个 Condition特点有界阻塞队列容量固定创建时指定公平性支持公平锁构造函数传入fairtrue适用场景生产者-消费者模型需要限制队列大小LinkedBlockingQueueBlockingQueueString queue new LinkedBlockingQueue(1000);底层结构单向链表 两把 ReentrantLockputLock takeLock特点可选有界默认 Integer.MAX_VALUE约等于无界吞吐量通常高于 ArrayBlockingQueue适用场景Executors.newFixedThreadPool()和newSingleThreadExecutor()的默认工作队列PriorityBlockingQueueBlockingQueueTask queue new PriorityBlockingQueue();底层结构最小堆无界特点带优先级的阻塞队列无界put 永远不会阻塞适用场景需要按优先级处理的任务队列DelayQueueBlockingQueueDelayedTask queue new DelayQueue();底层结构PriorityQueue ReentrantLock特点元素需要实现Delayed接口只有延迟到期的元素才能被取出适用场景延迟任务调度、缓存过期清理、订单超时取消SynchronousQueueBlockingQueueString queue new SynchronousQueue();底层结构不存储元素的特殊队列容量为 0特点每个 put 操作必须等待一个 take 操作直接传递一手交一手适用场景Executors.newCachedThreadPool()的默认工作队列LinkedTransferQueueTransferQueueString queue new LinkedTransferQueue();底层结构链表基于 CAS 的无锁结构特点融合了 SynchronousQueue 和 LinkedBlockingQueue 的特性支持transfer()方法生产者等待消费者接收适用场景高性能的生产者-消费者场景5.3 并发队列非阻塞ConcurrentLinkedQueueQueueString queue new ConcurrentLinkedQueue();底层结构单向链表基于 CAS 的无锁结构特点线程安全的无界非阻塞队列适合高并发场景适用场景多线程环境下需要高吞吐量的队列ConcurrentLinkedDequeDequeString deque new ConcurrentLinkedDeque();底层结构双向链表基于 CAS 的无锁结构特点线程安全的无界非阻塞双端队列适用场景多线程环境下需要双端操作的场景Queue 对比总结实现类底层结构有界/无界阻塞线程安全典型应用ArrayDeque循环数组可扩容否否栈 / 队列替代品PriorityQueue最小堆可扩容否否Top K / 任务调度ArrayBlockingQueue定长数组有界是是生产者-消费者LinkedBlockingQueue链表可选有界是是线程池工作队列PriorityBlockingQueue堆无界是是优先级任务队列DelayQueue堆无界是是延迟任务SynchronousQueue无存储有界(0)是是CachedThreadPoolLinkedTransferQueue链表无界是是高性能传递ConcurrentLinkedQueue链表无界否是高并发非阻塞队列ConcurrentLinkedDeque双向链表无界否是高并发双端队列六、工具类Collections 与 Arrays6.1 Collections 工具类// 不可变集合 ListString immutable Collections.unmodifiableList(list); // 线程安全包装 ListString syncList Collections.synchronizedList(new ArrayList()); MapString, Object syncMap Collections.synchronizedMap(new HashMap()); // 空集合不可变 ListString empty Collections.emptyList(); MapString, Object emptyMap Collections.emptyMap(); // 单元素集合不可变 SetString singleton Collections.singleton(only); // 排序、查找、翻转、打乱 Collections.sort(list); Collections.binarySearch(list, target); Collections.reverse(list); Collections.shuffle(list);6.2 JDK 9 的工厂方法// 不可变集合JDK 9 ListString list List.of(a, b, c); SetString set Set.of(a, b, c); MapString, Integer map Map.of(a, 1, b, 2); // JDK 10 的 copyOf ListString copy List.copyOf(mutableList);注意通过of()和copyOf()创建的集合是不可变的任何修改操作都会抛出UnsupportedOperationException。七、一张图总结Java 集合框架 │ ├── Collection单值集合 │ ├── List有序可重复 │ │ ├── ArrayList ← 最常用数组实现 │ │ ├── LinkedList ← 双向链表也实现 Deque │ │ ├── Vector ← 已过时 │ │ ├── Stack ← 已过时用 ArrayDeque 替代 │ │ └── CopyOnWriteArrayList ← 并发读多写少场景 │ │ │ ├── Set不可重复 │ │ ├── HashSet ← 最常用基于 HashMap │ │ ├── LinkedHashSet ← 保持插入顺序 │ │ ├── TreeSet ← 排序基于 TreeMap │ │ ├── EnumSet ← 枚举专用位运算极快 │ │ ├── CopyOnWriteArraySet← 并发场景 │ │ └── ConcurrentSkipListSet ← 并发 排序 │ │ │ └── Queue / Deque队列 │ ├── ArrayDeque ← 推荐的栈/队列实现 │ ├── PriorityQueue ← 最小堆 │ ├── ArrayBlockingQueue ← 有界阻塞队列 │ ├── LinkedBlockingQueue← 可选有界阻塞队列 │ ├── PriorityBlockingQueue ← 优先级阻塞队列 │ ├── DelayQueue ← 延迟队列 │ ├── SynchronousQueue ← 直接传递 │ ├── LinkedTransferQueue← 高性能传递 │ ├── ConcurrentLinkedQueue ← 无锁并发队列 │ └── ConcurrentLinkedDeque ← 无锁并发双端队列 │ └── Map键值对 ├── HashMap ← 最常用 ├── LinkedHashMap ← 维护顺序可实现 LRU ├── TreeMap ← 排序红黑树 ├── Hashtable ← 已过时 ├── ConcurrentHashMap ← 并发安全高性能 ├── ConcurrentSkipListMap ← 并发 排序 ├── WeakHashMap ← 弱引用 Key ├── IdentityHashMap ← 用 比较 Key ├── EnumMap ← 枚举 Key 专用 └── Properties ← 配置文件八、如何选择合适的集合选择集合时可以按照以下思路决策第一步确定存储类型存单个值 → CollectionList / Set / Queue存键值对 → Map第二步确定约束条件需要有序可重复 → List需要去重 → Set需要先进先出 / 优先级 → Queue需要键值映射 → Map第三步确定是否需要排序不需要排序 → Hash 系列HashMap、HashSet需要插入顺序 → Linked 系列LinkedHashMap、LinkedHashSet需要自然/自定义排序 → Tree 系列TreeMap、TreeSet第四步确定是否需要线程安全不需要 → 普通实现HashMap、ArrayList需要 → Concurrent 系列ConcurrentHashMap、CopyOnWriteArrayList总结Java 集合框架一共有 30 个实现类但日常开发中最常用的也就 7~8 个ArrayList、LinkedList、HashMap、LinkedHashMap、TreeMap、ConcurrentHashMap、HashSet、ArrayDeque。理解它们的底层数据结构和设计思想远比死记硬背 API 重要。后续的系列文章中我会对以下集合进行源码级深入分析HashMap数组 链表 红黑树的完整实现put/get/resize 逐行解读ConcurrentHashMap从 JDK 7 的分段锁到 JDK 8 的 CAS synchronizedArrayList动态数组的扩容机制、迭代器的 fail-fast 设计LinkedList双向链表操作与作为 Queue/Deque 的使用敬请期待本文为 Java 集合系列第 1 篇欢迎关注后续更新。 如果对你有帮助点赞收藏是对我最大的支持