目录
[一: 核心接口](#一: 核心接口)
[二: 核心集合类型](#二: 核心集合类型)
[1. List 集合](#1. List 集合)
[1.1 核心特性](#1.1 核心特性)
[1.2 常用实现类对比(面试必考)](#1.2 常用实现类对比(面试必考))
[1.3 List 核心方法(通用)](#1.3 List 核心方法(通用))
[2. Set 集合](#2. Set 集合)
[2.1 核心特性](#2.1 核心特性)
[2.2 常用实现类对比](#2.2 常用实现类对比)
[2.3 注意事项](#2.3 注意事项)
[3. Queue 队列 (FIFO)](#3. Queue 队列 (FIFO))
[3.1 核心特性](#3.1 核心特性)
[3.2 常用方法](#3.2 常用方法)
[4. Map集合](#4. Map集合)
[4.1 核心特性](#4.1 核心特性)
[4.2 常用实现类对比(核心)](#4.2 常用实现类对比(核心))
[4.3 Map核心方法 & 遍历 (面试常问)](#4.3 Map核心方法 & 遍历 (面试常问))
[三:面试高频考点 & 注意事项](#三:面试高频考点 & 注意事项)
[1. ArrayList VS LinkedList (必考)](#1. ArrayList VS LinkedList (必考))
[2. HashMap底层原理 (核心中的核心)](#2. HashMap底层原理 (核心中的核心))
[3. 集合线程](#3. 集合线程)
[4. 集合判空(易错点)](#4. 集合判空(易错点))
[5. 集合转数组 / 数组转集合](#5. 集合转数组 / 数组转集合)
[四: 总结](#四: 总结)
Java集合是用于存储、管理一组对象的容器,替代了早期的数组(数组长度固定、只能存同一类型),是Java核心基础(JDK 1.2 引入),也是面试高频考点。
集合框架主要分为 Collection(单列集合) 和 Map (双列集合)。
核心目标:提供高效的增删改查、遍历、排序等操作。

一: 核心接口
| 顶级接口 | 核心特性 | 子接口 / 实现类核心 |
|---|---|---|
| Collection | 所有单列集合的根接口,定义了增删查等通用方法 | List、Set、Queue |
| List | 有序(插入顺序)、可重复、有索引 | ArrayList(数组实现)、LinkedList(链表实现) |
| Set | 无序(HashSet)/ 有序(LinkedHashSet)、不可重复 | HashSet(基于 HashMap)、TreeSet(排序) |
| Queue | 先进先出(FIFO),支持队列操作 | LinkedList(双端队列)、PriorityQueue(优先级队列) |
| Map | 双列集合,存储键值对(key-value),key 不可重复 | HashMap(哈希表)、TreeMap(排序)、ConcurrentHashMap(线程安全) |
二: 核心集合类型
1. List 集合
1.1 核心特性
-
有序:元素的存储顺序 = 取出顺序
-
可重复:允许添加相同的元素
-
有索引:支持通过
get(int index)随机访问
1.2 常用实现类对比(面试必考)
| 实现类 | 底层实现 | 线程安全 | 访问效率 | 增删效率 | 扩容机制 | 适用场景 |
|---|---|---|---|---|---|---|
| ArrayList | 动态数组(Object []) | ❌ | 高(随机访问) | 低(中间增删需移动元素) | 初始容量 10,扩容为原容量 1.5 倍(newCapacity = oldCapacity + (oldCapacity>> 1)) | 读多写少、随机访问频繁 |
| LinkedList | 双向链表 | ❌ | 低(需遍历找元素) | 高(仅需修改节点指针) | 无扩容(链表按需分配节点) | 写多读少、频繁增删(如队列 / 栈) |
| Vector | 动态数组 | ✅ (方法加 synchronized) | 中 | 低 | 初始容量 10,扩容为原容量 2 倍 | 多线程场景(已过时,推荐 CopyOnWriteArrayList) |
1.3 List 核心方法(通用)
java
List<String> list = new ArrayList<>();
list.add("a"); // 添加元素
list.add(1, "b"); // 指定索引添加
list.get(0); // 获取索引0元素
list.set(0, "c"); // 修改索引0元素
list.remove(0); // 删除索引0元素
list.size(); // 获取长度
list.contains("c"); // 判断是否包含
list.clear(); // 清空
// --------------遍历(三种方式)----------------
// 1. 普通for循环(有索引)
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 2. 增强for循环
for (String s : list) {
System.out.println(s);
}
// 3. 迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
2. Set 集合
2.1 核心特性
-
不可重复:添加重复元素会被忽略(底层依赖
equals()和hashCode()) -
无序:HashSet是无序的(基于哈希表),LinkedHashSet 是有序的(保留插入顺序),TreeSet 是排序的(自然排序 / 自定义排序)
2.2 常用实现类对比
| 实现类 | 底层实现 | 有序性 | 排序性 | 线程安全 | 去重原理 | 适用场景 |
|---|---|---|---|---|---|---|
| HashSet | 基于 HashMap(key 存元素,value 存固定对象) | ❌(哈希无序) | ❌ | ❌ | 先比较 hashCode (),再比较 equals () | 无需有序、快速去重 |
| LinkedHashSet | 继承 HashSet + 双向链表 | ✅(插入顺序) | ❌ | ❌ | 同 HashSet,链表维护顺序 | 去重且需保留插入顺序 |
| TreeSet | 基于 TreeMap(红黑树) | ✅(排序后) | ✅(自然排序 / Comparator) | ❌ | 基于比较器(compareTo ()/Comparator) | 去重且需排序 |
2.3 注意事项
(1)HashSet 去重前提 :元素类必须重写 hashCode() 和 equals()(否则无法正确去重)
java
class Student {
private String name;
private int age;
// 必须重写 hashCode 和 equals
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
(2)TreeSet 排序 :元素类需实现 Comparable 接口,或创建 TreeSet 时传入 Comparator
java
// 方式1:实现 Comparable
class Student implements Comparable<Student> {
@Override
public int compareTo(Student o) {
return this.age - o.age; // 按年龄升序
}
}
// 方式2:传入 Comparator
TreeSet<Student> set = new TreeSet<>((s1, s2) -> s2.age - s1.age); // 按年龄降序
3. Queue 队列 (FIFO)
3.1 核心特性
-
先进先出(FIFO),支持队列头部 / 尾部操作
-
LinkedList 是 Queue 的主要实现类(双端队列 Deque),PriorityQueue 是优先级队列(按优先级出队)
3.2 常用方法
java
Queue<String> queue = new LinkedList<>();
queue.offer("a"); // 添加元素(推荐,失败返回false)
queue.poll(); // 移除并返回队首(队空返回null)
queue.peek(); // 获取队首(队空返回null)
// 栈操作(Deque)
Deque<String> deque = new LinkedList<>();
deque.push("a"); // 入栈
deque.pop(); // 出栈
4. Map集合
4.1 核心特性
-
存储 key-value 映射,key 唯一(重复添加会覆盖 value),value 可重复
-
key 的特性同 Set(HashSet 对应 HashMap,TreeSet 对应 TreeMap)
4.2 常用实现类对比(核心)
| 实现类 | 底层实现 | 线程安全 | 有序性 | 空键 / 空值 | 扩容机制 | 适用场景 |
|---|---|---|---|---|---|---|
| HashMap | 哈希表(数组 + 链表 + 红黑树,JDK 1.8+) | ❌ | ❌ | ✅(仅 1 个空键,多个空值) | 初始容量 16,负载因子 0.75,扩容为 2 倍 | 单线程、快速存取 |
| LinkedHashMap | 继承 HashMap + 双向链表 | ❌ | ✅(插入 / 访问顺序) | ✅ | 同 HashMap | 需保留键的顺序 |
| TreeMap | 红黑树 | ❌ | ✅(key 排序) | ❌(不支持空键) | 无扩容(红黑树动态调整) | key 需排序的场景 |
| Hashtable | 哈希表 | ✅(方法加 synchronized) | ❌ | ❌(不支持空键 / 空值) | 初始容量 11,扩容为 2 倍 + 1 | 已过时,替代用 ConcurrentHashMap |
| ConcurrentHashMap | 分段锁(JDK 1.7)/ CAS + 同步锁(JDK 1.8) | ✅(高效线程安全) | ❌ | ✅(空值不推荐) | 同 HashMap | 多线程高并发场景 |
4.3 Map核心方法 & 遍历 (面试常问)
java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1); // 添加键值对
map.put("b", 2);
map.get("a"); // 获取value(返回1)
map.remove("b"); // 删除键值对
map.containsKey("a"); // 判断key是否存在
map.size(); // 获取键值对数量
// 遍历(三种方式)
// 1. 遍历key集
for (String key : map.keySet()) {
System.out.println(key + ":" + map.get(key));
}
// 2. 遍历entry集(推荐,效率高)
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
// 3. 遍历value集
for (Integer value : map.values()) {
System.out.println(value);
}
三:面试高频考点 & 注意事项
1. ArrayList VS LinkedList (必考)
-
访问效率 :ArrayList 基于数组,随机访问(
get(index))O (1),LinkedList 遍历找元素 O (n); -
增删效率:LinkedList 增删仅修改指针 O (1),ArrayList 中间增删需移动元素 O (n);
-
内存:ArrayList 有扩容冗余,LinkedList 每个节点存前后指针,内存开销更大。
2. HashMap底层原理 (核心中的核心)
-
JDK 1.8 结构:数组 + 链表 + 红黑树;
-
哈希计算 :key 的 hashCode () 经过扰动函数得到哈希值,再通过
(数组长度-1) & 哈希值确定数组索引; -
链表转红黑树:链表长度 ≥ 8 且数组长度 ≥ 64 时,转为红黑树(提升查询效率);
-
负载因子 0.75:平衡空间和时间,超过阈值(容量 ×0.75)触发扩容;
-
线程不安全:并发修改可能导致链表成环(死循环),多线程用 ConcurrentHashMap。
3. 集合线程
| 非线程安全集合 | 对应的线程安全替代方案 | 特点 |
|---|---|---|
| ArrayList | CopyOnWriteArrayList | 写时复制,适合读多写少 |
| HashSet | CopyOnWriteArraySet | 基于 CopyOnWriteArrayList |
| HashMap | ConcurrentHashMap | 高效线程安全(分段锁 / CAS) |
| Vector/Hashtable | 不推荐使用 | 加锁粒度大,效率低 |
4. 集合判空(易错点)
-
❌:
if (list == null)(仅判断是否初始化) -
✅:
if (list == null || list.isEmpty())(先判空指针,再判是否有元素)
5. 集合转数组 / 数组转集合
java
// 集合转数组
List<String> list = new ArrayList<>();
list.add("a");
String[] arr = list.toArray(new String[0]); // 推荐,自动适配长度
// 数组转集合(注意:返回的是固定长度集合,不能增删)
String[] arr = {"a", "b"};
List<String> list = Arrays.asList(arr);
// 若需可修改集合:
List<String> list2 = new ArrayList<>(Arrays.asList(arr));
四: 总结
-
核心分类:Collection(List/Set/Queue)是单列集合,Map 是双列集合,核心区别是是否有索引、是否可重复
-
选型原则 :读多写少用 ArrayList/HashMap, 写多读少用 LinkedList,去重用 HashSet,排序用 TreeSet/TreeMap,多线程用 ConcurrentHashMap/CopyOnWriteArrayList
-
面试重点:ArrayList vs LinkedList、HashMap 底层原理、集合线程安全、Set 去重原理
