Java 集合类全景介绍

Java 集合类全景介绍

面向前端开发者。如果你用 JS 的 ArraySetMapObject,这篇文章帮你一次性认清 Java 所有集合类。


目录

  1. [先看 JS:你已会的集合类型](#先看 JS:你已会的集合类型)
  2. [Java 集合框架全景图](#Java 集合框架全景图)
  3. List:有序可重复
  4. Set:无序不重复
  5. [Queue / Deque:队列与双端队列](#Queue / Deque:队列与双端队列)
  6. Map:键值对
  7. 线程安全集合
  8. 怎么选?决策速查表
  9. [与 JS 的终极对照表](#与 JS 的终极对照表)

1. 先看 JS:你已会的集合类型

js 复制代码
// JS 里的集合就这几种
const arr  = [1, 2, 3];           // ← 什么都能干:列表 + 队列 + 栈
const set  = new Set([1, 2, 2]);  // ← 去重
const map  = new Map();           // ← 键值对
const obj  = { a: 1, b: 2 };      // ← 也是键值对

Java 不一样------每种数据结构有专门的类,一个场景一个最优解。

JS Java 对应 说明
Array(列表) ArrayList 最常用,动态数组
Array(要用队列/栈) ArrayDeque / LinkedList Java 不会用一个类干所有事
Set HashSet / TreeSet 去重集合
Map HashMap / TreeMap 键值对
Object(字符串 key) HashMap<String, V> Java 没有字面量对象

2. Java 集合框架全景图

复制代码
                          Iterable (接口)
                              │
                        Collection (接口)
                         /     |      \
                       List   Set    Queue/Deque
                        │      │        │
              ┌────┴────┐  ┌──┴──┐  ┌──┴──┐
         ArrayList  LinkedList  HashSet  PriorityQueue
              │                  │
            Vector          LinkedHashSet
                             TreeSet


                          Map (独立体系)
                         /    |      \
                    HashMap  TreeMap  Hashtable
                       │
                LinkedHashMap
                       │
               ConcurrentHashMap

记住:Collection 是单值集合,Map 是键值对,两条线不互相继承。


3. List:有序可重复

和 JS 的 Array 最像。有索引、可重复、有顺序。

3.1 ArrayList(⭐⭐⭐⭐⭐ 最常用)

java 复制代码
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.get(0);      // "张三"
list.size();      // 3
list.remove(1);   // 删除"李四"
特性 说明
底层 Object[] 动态数组
查询 O(1) --- 直接通过下标访问
插入/删除 O(n) --- 需要搬移后续元素
扩容 默认 10 → 1.5 倍扩容
适用 读多写少(查数据快)

3.2 LinkedList

java 复制代码
List<String> list = new LinkedList<>();
list.add("张三");
list.addFirst("队首");   // Deque 的方法
list.addLast("队尾");
特性 说明
底层 双向链表
查询 O(n) --- 需要从头遍历
插入/删除 O(1) --- 改指针即可(但定位到位置还是 O(n))
额外能力 实现了 Deque,可当队列/栈用
适用 频繁头尾增删;但大部分场景 ArrayList 更好(内存连续,CPU 缓存友好)

3.3 Vector(⚠ 过时,不推荐)

java 复制代码
// 和 ArrayList 几乎一样,但所有方法加了 synchronized
// JDK 1.0 的老古董,现在用 Collections.synchronizedList() 或 CopyOnWriteArrayList
List<String> vec = new Vector<>();  // ❌ 不推荐

3.4 ArrayList vs LinkedList 速查

ArrayList LinkedList
底层 数组 双向链表
get(i) O(1) O(n)
add(E) O(1) 均摊 O(1)
add(0, E) O(n) O(1)
内存 连续,浪费少 每个节点额外存 prev/next 指针
用哪个? 90% 选它 只在频繁头插时考虑

4. Set:无序不重复

和 JS 的 new Set() 一样------去重。

4.1 HashSet(⭐⭐⭐⭐⭐ 最常用)

java 复制代码
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Python");
set.add("Java");      // 重复,被忽略
set.size();           // 2
set.contains("Java"); // true
特性 说明
底层 就是 HashMap!(value 固定为 PRESENT 占位符)
顺序 无序
复杂度 add/remove/contains 都是 O(1)
去重依据 hashCode() + equals()

4.2 LinkedHashSet

java 复制代码
Set<String> set = new LinkedHashSet<>();
set.add("C");
set.add("A");
set.add("B");
// 遍历顺序:C → A → B(保持插入顺序)
特性 说明
底层 LinkedHashMap(HashSet + 双向链表维护顺序)
顺序 保持插入顺序
代价 比 HashSet 多一点点内存

4.3 TreeSet

java 复制代码
Set<Integer> set = new TreeSet<>();
set.add(5);
set.add(1);
set.add(3);
// 遍历顺序:1 → 3 → 5(自然排序)
特性 说明
底层 TreeMap(红黑树)
顺序 自动排序(自然序或 Comparator)
复杂度 O(log n)
要求 元素必须实现 Comparable 或传 Comparator

4.4 Set 速查

HashSet LinkedHashSet TreeSet
顺序 无序 插入序 排序序
复杂度 O(1) O(1) O(log n)
去重依据 hashCode + equals hashCode + equals compareTo / Comparator
用哪个? 只要去重 去重 + 保持顺序 去重 + 自动排序

5. Queue / Deque:队列与双端队列

5.1 Queue 接口方法

java 复制代码
Queue<String> q = new LinkedList<>();

// 三组方法,每组两个:一个抛异常,一个返回特殊值
q.add("A");       // 入队,失败抛异常
q.offer("B");     // 入队,失败返回 false  ← 推荐

q.remove();       // 出队,空队抛异常
q.poll();         // 出队,空队返回 null   ← 推荐

q.element();      // 看队首,空队抛异常
q.peek();         // 看队首,空队返回 null  ← 推荐

5.2 实现类

底层 场景
LinkedList 双向链表 实现了 List + Deque,既能当列表又能当队列
PriorityQueue 二叉堆 优先级队列---每次 poll 出最小/最大的元素
ArrayDeque 循环数组 推荐---比 LinkedList 快,当栈/队列首选

5.3 ArrayDeque:栈和队列的最佳实践

java 复制代码
// 当栈用(替代 Stack)
Deque<String> stack = new ArrayDeque<>();
stack.push("A");       // 压栈
stack.push("B");
stack.pop();           // "B"(后进先出)

// 当队列用
Deque<String> queue = new ArrayDeque<>();
queue.offer("A");      // 入队
queue.offer("B");
queue.poll();          // "A"(先进先出)

Java 官方推荐 用 ArrayDeque 代替 Stack(Stack 是 JDK 1.0 的过时类)。


6. Map:键值对

和 JS 的 Map / Object 对应。Java 中最常用的数据结构之一。

6.1 HashMap(⭐⭐⭐⭐⭐ 最常用)

java 复制代码
Map<String, Integer> map = new HashMap<>();
map.put("张三", 95);
map.put("李四", 87);
map.get("张三");        // 95
map.containsKey("李四"); // true
map.remove("张三");

// 遍历
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

// Java 8+ Lambda
map.forEach((k, v) -> System.out.println(k + " = " + v));
特性 说明
底层 数组 + 链表 + 红黑树
顺序 无序
get/put O(1) ~ O(log n)
null 允许一个 null key,多个 null value
线程安全
深入原理 Java-HashMap原理详解.md

6.2 LinkedHashMap

java 复制代码
Map<String, Integer> map = new LinkedHashMap<>();
map.put("C", 3);
map.put("A", 1);
map.put("B", 2);
// 遍历顺序:C → A → B(保持插入顺序)
特性 说明
底层 HashMap + 双向链表
顺序 保持插入顺序(或 accessOrder=true 按访问顺序,实现 LRU)
java 复制代码
// LRU 缓存的经典实现
Map<String, Integer> lru = new LinkedHashMap<String, Integer>(16, 0.75f, true) {
    @Override
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > 100;  // 超过 100 条自动删除最老的
    }
};

6.3 TreeMap

java 复制代码
Map<String, Integer> map = new TreeMap<>();
map.put("C", 3);
map.put("A", 1);
map.put("B", 2);
// 遍历顺序:A → B → C(按 key 自然排序)
特性 说明
底层 红黑树
顺序 按 key 排序
get/put O(log n)
null key ❌ 不允许(因为要排序、比较)

6.4 Hashtable(⚠ 过时,不推荐)

java 复制代码
Map<String, Integer> t = new Hashtable<>();  // ❌ 不推荐
// 全方法 synchronized,性能差
// 不允许 null key/value
// 用 ConcurrentHashMap 替代

6.5 Map 速查

HashMap LinkedHashMap TreeMap
顺序 无序 插入序 / 访问序 key 排序序
get/put O(1)~O(log n) O(1)~O(log n) O(log n)
null key
内存 中(多链表指针) 中(树节点)
用哪个? 绝大多数场景 需要有序遍历 需要按 key 排序

7. 线程安全集合

前面所有的集合类都不是线程安全的(HashMap、ArrayList 等)。多线程场景需要用以下替代:

非线程安全 线程安全替代 方案
HashMap ConcurrentHashMap CAS + synchronized 桶级锁
ArrayList CopyOnWriteArrayList 写时复制,读多写少
HashSet CopyOnWriteArraySet 写时复制
HashSet ConcurrentHashMap.newKeySet() 基于 ConcurrentHashMap
ArrayDeque ConcurrentLinkedDeque 无锁 CAS
LinkedList(Queue) ConcurrentLinkedQueue 无锁 CAS
任意 Collections.synchronizedXXX() 全方法 synchronized(性能差)

选型建议

复制代码
读多写少  → CopyOnWriteArrayList / CopyOnWriteArraySet
读写均衡  → ConcurrentHashMap / ConcurrentLinkedQueue
简单场景  → Collections.synchronizedList()(不推荐,性能差)

8. 怎么选?决策速查表

复制代码
                        ┌─── 需要键值对? ───→ Map
                        │         ├── 无序 → HashMap
                        │         ├── 按插入序 → LinkedHashMap
                        │         └── 按 key 排序 → TreeMap
                        │
需要集合? ──┤
                        │
                        └─── 只需要值? ───→ Collection
                                  │
                    ┌─────────────┼─────────────┐
                    │             │             │
                 需要重复?    需要去重?    需要 FIFO/LIFO?
                    │             │             │
                   List          Set          Queue/Deque
                    │             │             │
              ┌─────┴─────┐  ┌───┴───┐    ┌───┴───┐
          读多:      头尾操作多: 无序:  保持序:  排序:  队列:  双端/栈:
        ArrayList   LinkedList  HashSet Linked-  TreeSet 优先队列: ArrayDeque
                                         HashSet         PriorityQueue

9. 与 JS 的终极对照表

JS Java 说明
[1, 2, 3] ArrayList 动态数组,最常用
[] 当队列 .push()+.shift() ArrayDeque / LinkedList Java 不应该用 List 当队列
[] 当栈 .push() + .pop() ArrayDeque(用 push/pop 替代过时的 Stack
new Set([1,2,3]) HashSet 去重
--- TreeSet 去重 + 排序(JS 没有内置等价物)
new Map() HashMap 键值对
{}(字符串 key) HashMap<String, V> 最相似的使用方式
Map 保持插入序 LinkedHashMap JS Map 默认保持插入序,Java 需要指定
--- TreeMap key 排序的 Map(JS 没有)
无(单线程) ConcurrentHashMap 多线程安全 Map

一句话记住:ArrayList + HashMap 覆盖 80% 场景,HashSet 去重,ArrayDeque 当栈/队列,LinkedHashMap 保序,TreeMap/TreeSet 排序,并发上 ConcurrentHashMap。

相关推荐
钱栈up1 小时前
"Flowable 工作流引擎进阶实战(高级篇):任务分配、流程变量与监听器"
java
Iruoyaoxh1 小时前
类和对象~
开发语言·c++
程序喵大人1 小时前
【C++进阶】STL算法与函数对象 - 04 find、count和any_of把查询写成意图
开发语言·c++·算法
豆沙沙包?1 小时前
c++中引用(P7-P11)
java·c++·算法
Livia要学习1 小时前
Python装饰器
开发语言·python
一直都在5721 小时前
LangChain4j精讲
开发语言·人工智能
wuminyu2 小时前
虚拟线程底层ForkJoinPool的工作窃取算法机制
java·linux·c语言·jvm·c++
吹什么轩2 小时前
c++复习:c++11:lambda表达式
开发语言·c++
不会代码的小猴2 小时前
标准模板库(STL)
开发语言·c++·笔记·算法