集合类
约 1177 字大约 4 分钟
2026-03-27
一、集合类概述
集合用于存储一组对象,和数组相比,集合的长度可动态变化,操作也更灵活。Java 集合框架主要位于 java.util 包中。
集合框架可以分为两大类:
Collection:单列集合,一个元素一个元素地存Map:双列集合,以键值对形式存储
二、集合框架体系
2.1 Collection 体系
Collection 下面最常见的子接口有:
List:有序、可重复Set:无序或排序后有序、不可重复
常见实现类:
ArrayListLinkedListHashSetLinkedHashSetTreeSet
2.2 Map 体系
Map 存储的是 key-value 键值对。
常见实现类:
HashMapLinkedHashMapTreeMapHashtable
三、List 集合
3.1 List 的特点
- 元素有序,按插入顺序保存
- 元素可以重复
- 可以通过索引访问元素
import java.util.ArrayList;
import java.util.List;
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("Java");
System.out.println(list.get(0));
System.out.println(list.size());3.2 ArrayList
ArrayList 底层是动态数组,特点如下:
- 查询快
- 尾部追加效率较高
- 中间插入、删除相对较慢
适合场景:
- 查询多、增删少
3.3 LinkedList
LinkedList 底层是双向链表,特点如下:
- 插入、删除节点效率较高
- 按索引查询较慢
它还实现了队列和双端队列的相关能力。
import java.util.LinkedList;
LinkedList<String> queue = new LinkedList<>();
queue.addFirst("A");
queue.addLast("B");
System.out.println(queue.removeFirst());四、Set 集合
4.1 Set 的特点
- 元素不能重复
- 没有索引
是否重复,通常由 equals() 和 hashCode() 决定。
4.2 HashSet
HashSet 底层基于哈希表实现:
- 存取速度快
- 元素无序
- 允许一个
null
import java.util.HashSet;
import java.util.Set;
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(1);
System.out.println(set); // 不重复4.3 LinkedHashSet
LinkedHashSet 在哈希表基础上维护插入顺序,因此:
- 去重
- 能保持插入顺序
适合既要去重又要保持展示顺序的场景。
4.4 TreeSet
TreeSet 可以对元素进行排序。
排序方式有两种:
- 自然排序:元素类实现
Comparable - 定制排序:传入
Comparator
import java.util.Set;
import java.util.TreeSet;
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(3);
treeSet.add(1);
treeSet.add(2);
System.out.println(treeSet); // [1, 2, 3]五、Map 集合
5.1 Map 的特点
- 存储键值对
key不允许重复value可以重复
5.2 HashMap
HashMap 是开发中最常用的映射集合。
特点:
- 查询效率高
- 允许一个
nullkey - 允许多个
nullvalue - 不保证顺序
import java.util.HashMap;
import java.util.Map;
Map<String, Integer> scoreMap = new HashMap<>();
scoreMap.put("Tom", 90);
scoreMap.put("Jerry", 95);
scoreMap.put("Tom", 99);
System.out.println(scoreMap.get("Tom"));重复的 key 会覆盖旧值。
5.3 LinkedHashMap
LinkedHashMap 可以保持插入顺序,适合需要按加入顺序展示数据的场景。
5.4 TreeMap
TreeMap 会按照 key 排序。
import java.util.Map;
import java.util.TreeMap;
Map<String, Integer> map = new TreeMap<>();
map.put("c", 3);
map.put("a", 1);
map.put("b", 2);
System.out.println(map); // {a=1, b=2, c=3}六、集合的遍历方式
6.1 for 循环
适合有索引的 List。
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}6.2 增强 for 循环
for (String item : list) {
System.out.println(item);
}6.3 Iterator 迭代器
import java.util.Iterator;
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}6.4 Map 的遍历
遍历 Map 推荐使用 entrySet()。
for (Map.Entry<String, Integer> entry : scoreMap.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}七、Collections 工具类
Collections 是集合的工具类,提供排序、反转、查找等操作。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
List<Integer> nums = new ArrayList<>();
nums.add(3);
nums.add(1);
nums.add(2);
Collections.sort(nums);
Collections.reverse(nums);
System.out.println(nums);常见方法:
sort()reverse()shuffle()max()min()
八、集合选型建议
| 场景 | 推荐集合 |
|---|---|
| 查询多,增删少 | ArrayList |
| 中间插入删除频繁 | LinkedList |
| 去重 | HashSet |
| 去重且保留插入顺序 | LinkedHashSet |
| 自动排序 | TreeSet、TreeMap |
| 键值映射 | HashMap |
| 需要保持键顺序 | LinkedHashMap |
九、常见易错点
9.1 在 for-each 中直接删除元素
下面写法可能抛出 ConcurrentModificationException:
for (String item : list) {
if ("b".equals(item)) {
list.remove(item);
}
}正确方式是使用迭代器删除:
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if ("b".equals(it.next())) {
it.remove();
}
}9.2 自定义对象放入 HashSet 却没重写 equals 和 hashCode
如果不重写,集合无法按“内容”判断是否重复。
9.3 混淆 Collection 和 Collections
Collection是集合根接口Collections是集合工具类
9.4 误以为 HashMap 有序
HashMap 默认不保证顺序。如果需要顺序,应该选择 LinkedHashMap 或 TreeMap。
十、线程安全问题
大多数常用集合类默认都不是线程安全的,例如:
ArrayListHashSetHashMap
如果在多线程环境下共享集合,需要考虑:
- 使用同步包装:
Collections.synchronizedList(...) - 使用并发集合:如
ConcurrentHashMap、CopyOnWriteArrayList
十一、实践建议
- 先根据“是否重复、是否有序、是否需要键值对”决定集合类型
- 默认列表优先考虑
ArrayList - 默认映射优先考虑
HashMap - 自定义对象参与去重或作为 key 时,规范重写
equals和hashCode - 不要为了“性能”盲目选择
LinkedList,多数业务场景下ArrayList更合适
