一、集合框架核心组件概览
Java 集合框架( java.util 包)核心分为三大接口+工具类体系,适配不同数据存储与操作场景:
- List:有序可重复,支持随机访问,主流实现包括基于数组的 ArrayList 和基于链表的 LinkedList 。
- Set:无序不可重复,支持快速去重,主流实现有哈希存储的 HashSet 、有序存储的 TreeSet 以及保留插入顺序的 LinkedHashSet 。
- Map:键值对(K-V)存储,Key 具有唯一性,主流实现包括哈希映射的 HashMap 、有序映射的 TreeMap 和保序的 LinkedHashMap 。
- 工具类: Collections 提供集合通用算法, Arrays 专注数组相关操作, Objects 处理对象空值校验等,均为简化集合操作的高频工具。
二、三大核心接口常用函数(高频场景版)
1. List 接口(有序可重复)
- add(E e) 和 add(int idx, E e) :分别用于在列表尾部和指定位置添加元素,适配基础数据插入场景。
- get(int idx) :通过索引获取元素,是 ArrayList 随机访问的核心优势功能。
- remove(int idx) 和 remove(Object o) :分别按索引和元素本身删除数据,满足精准移除需求。
- sort(Comparator) :支持自定义排序规则,比如按数值降序、对象字段排序等场景。
- subList(int from, int to) :截取子列表(属于原列表的视图),常用于列表切片和区间数据处理。
- removeIf(Predicate) :按条件批量删除元素,例如移除列表中所有偶数。
- indexOf(Object o) :查找元素首次出现的索引,实现元素位置精准定位。
2. Set 接口(无序不可重复)
- add(E e) :添加元素时自动去重,若元素已存在则返回 false,适用于去重存储场景。
- contains(Object o) :判断元素是否存在, HashSet 中该操作效率为 O(1),是高效存在性校验的首选。
- retainAll(Collection) :保留集合与目标集合的交集元素,用于交集运算。
- removeAll(Collection) :移除集合中属于目标集合的元素,实现差集运算。
- iterator() :获取迭代器,支持安全遍历集合,避免并发修改异常。
3. Map 接口(K-V 映射)
- put(K k, V v) :存入键值对,若 Key 已存在则覆盖对应 Value,是基础映射存储功能。
- getOrDefault(K k, V def) :获取 Key 对应的 Value,若 Key 不存在则返回默认值,可避免空指针,适用于计数等场景。
- entrySet() :获取所有键值对组成的 Set 集合,是高效遍历所有映射的核心方法。
- forEach(BiConsumer) :通过 Lambda 表达式遍历键值对,大幅简化遍历代码。
- computeIfAbsent(K, Function) :当 Key 不存在时自动创建对应的 Value,常用于分组场景(如字母异位词分组)。
- replaceAll(BiFunction) :按指定规则批量替换所有 Value,实现映射值的批量更新。
三、高频实战场景代码模板
1. List 核心操作(去重、排序、过滤)
java
// 初始化与去重(保留原顺序)
List<Integer> numList = new ArrayList<>(Arrays.asList(5,2,8,2,9,1));
List<Integer> distinctList = new ArrayList<>(new LinkedHashSet<>(numList)); // 结果:[5,2,8,9,1]
// 排序(自然升序 + 自定义降序)
Collections.sort(numList); // 自然升序排序
numList.sort((a, b) -> b - a); // 自定义降序排序
// 条件过滤(移除偶数)
numList.removeIf(num -> num % 2 == 0);
// 子列表切片(左闭右开区间 [1,4))
List<Integer> subList = numList.subList(1, 4);
2. Set 集合运算(交集、并集、差集)
java
Set<Integer> set1 = new HashSet<>(Arrays.asList(1,2,3,4));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3,4,5,6));
// 并集:合并两个集合所有元素(自动去重)
Set<Integer> unionSet = new HashSet<>(set1);
unionSet.addAll(set2); // 结果:[1,2,3,4,5,6]
// 交集:保留两个集合共有的元素
Set<Integer> intersectSet = new HashSet<>(set1);
intersectSet.retainAll(set2); // 结果:[3,4]
// 差集:保留 set1 中有但 set2 中没有的元素
Set<Integer> diffSet = new HashSet<>(set1);
diffSet.removeAll(set2); // 结果:[1,2]
3. Map 实战(计数、分组、遍历)
java
// 1. 单词计数(利用 getOrDefault 避免空指针)
String[] words = {"apple", "banana", "apple", "orange", "banana", "apple"};
Map<String, Integer> countMap = new HashMap<>();
for (String word : words) {
countMap.put(word, countMap.getOrDefault(word, 0) + 1);
}
// 2. 字母异位词分组(computeIfAbsent 自动创建空列表)
String[] strs = {"eat", "tea", "tan", "ate", "nat", "bat"};
Map<String, List<String>> groupMap = new HashMap<>();
for (String s : strs) {
char[] chars = s.toCharArray();
Arrays.sort(chars);
String key = new String(chars);
groupMap.computeIfAbsent(key, k -> new ArrayList<>()).add(s);
}
// 3. Lambda 表达式简化键值对遍历
countMap.forEach((key, value) -> System.out.println(key + ":" + value + "次"));
4. 工具类核心用法(Collections/Arrays)
java
// Collections 工具类:反转列表、查找最值
List<Integer> list = new ArrayList<>(Arrays.asList(3,1,4,1,5));
Collections.reverse(list); // 反转列表元素顺序
int max = Collections.max(list); // 获取列表最大值
int min = Collections.min(list); // 获取列表最小值
// Arrays 工具类:数组排序、数组转 List、二分查找
int[] arr = {5,2,9,1};
Arrays.sort(arr); // 对数组进行升序排序
List<Integer> arrToList = new ArrayList<>(Arrays.asList(1,2,3)); // 数组转为可修改的 List
int idx = Arrays.binarySearch(arr, 5); // 二分查找元素(数组需先排序)
四、关键知识点与避坑指南
- 泛型使用规范:集合泛型必须指定引用类型(如 Integer 而非 int ),否则会出现类型转换异常,影响程序稳定性。
- List 子列表注意事项: subList 方法返回的是原列表的视图,而非新集合,修改子列表会同步影响原列表,需谨慎操作。
- Set 去重原理:Set 的去重依赖元素的 equals() 和 hashCode() 方法,自定义对象若需实现去重,必须重写这两个方法。
- Map Key 选择原则:Key 应选用不可变类型(如 String、Integer),若使用可变对象作为 Key,修改后可能导致无法正常查找对应的 Value。
- 并发安全问题:默认集合(如 ArrayList、HashMap)均非线程安全,多线程并发场景需使用 java.util.concurrent 包下的类(如 ConcurrentHashMap、CopyOnWriteArrayList)。
- Lambda 简化技巧:JDK8+ 中, Comparator 、 Predicate 等接口可通过 Lambda 表达式简写,例如用 (a,b)->b-a 替代复杂的匿名内部类,精简代码。
五、总结
Java 集合框架的核心设计思路是"接口定义规范、实现类适配场景",实战中需根据需求选择合适的实现类:去重选 HashSet、随机访问选 ArrayList、有序映射选 TreeMap。掌握 List/Set/Map 的高频函数与工具类用法,结合 Lambda 和 Stream 特性,可大幅提升代码编写效率。