当前位置: 首页 > news >正文

Java 集合工具类

Java 集合工具类(java.util.Collections)详解

java.util.Collections 是 Java 提供的集合操作工具类,包含大量静态方法,用于操作或返回集合(如排序、查找、同步控制等)。它弥补了集合实现类自身方法的不足,简化了常见的集合操作。本文将详细讲解其核心功能和常用方法,结合代码示例说明用法。

一、Collections 工具类的特点

  1. 静态方法:所有方法均为 static,无需创建实例,直接通过类名调用(Collections.方法名())。
  2. 通用性:适用于 Collection 框架中的各种集合(ListSetMap 等)。
  3. 功能丰富:涵盖排序、查找、替换、同步化、不可修改化等操作。

二、核心功能与常用方法

1. 排序操作(针对 List

Collections 提供了多种排序方法,仅适用于 List(因 SetMap 的排序依赖其实现类自身特性,如 TreeSetTreeMap)。

方法声明功能描述
static <T extends Comparable<? super T>> void sort(List<T> list)List自然顺序排序(元素需实现 Comparable
static <T> void sort(List<T> list, Comparator<? super T> c)自定义比较器排序
static void reverse(List<?> list)反转 List 中元素的顺序
static void shuffle(List<?> list)随机打乱 List 中元素的顺序(洗牌)
static <T> void swap(List<?> list, int i, int j)交换 List 中指定索引 ij 的元素

代码示例:排序操作

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;public class CollectionsSortDemo {public static void main(String[] args) {List<Integer> numbers = new ArrayList<>();numbers.add(3);numbers.add(1);numbers.add(2);System.out.println("初始列表:" + numbers); // [3, 1, 2]// 1. 自然排序(从小到大)Collections.sort(numbers);System.out.println("自然排序后:" + numbers); // [1, 2, 3]// 2. 自定义比较器(从大到小)Collections.sort(numbers, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1; // 反转比较顺序}});System.out.println("自定义排序后:" + numbers); // [3, 2, 1]// 3. 反转列表Collections.reverse(numbers);System.out.println("反转后:" + numbers); // [1, 2, 3]// 4. 随机打乱(每次结果不同)Collections.shuffle(numbers);System.out.println("打乱后:" + numbers); // 例如:[2, 3, 1]// 5. 交换元素(索引0和2)Collections.swap(numbers, 0, 2);System.out.println("交换后:" + numbers); // 例如:[1, 3, 2]}
}
2. 查找与替换(针对 List

提供在 List 中查找元素、替换元素的方法,部分方法依赖排序(如二分查找)。

方法声明功能描述
static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)二分查找指定元素的索引(需先排序,未找到返回负数)
static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)基于比较器的二分查找(需先按该比较器排序)
static <T> int indexOfSubList(List<?> source, List<?> target)查找子列表 targetsource 中首次出现的索引(未找到返回 -1
static <T> int lastIndexOfSubList(List<?> source, List<?> target)查找子列表 targetsource 中最后出现的索引
static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)list 中所有 oldVal 替换为 newVal(返回是否有替换)
static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)返回集合中自然顺序最大的元素
static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)返回集合中比较器定义的最大元素
static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)返回集合中自然顺序最小的元素
static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp)返回集合中比较器定义的最小元素

代码示例:查找与替换

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class CollectionsSearchDemo {public static void main(String[] args) {// 1. 二分查找(需先排序)List<Integer> nums = new ArrayList<>();nums.add(10);nums.add(20);nums.add(30);nums.add(40);Collections.sort(nums); // 先排序(必须!)int index = Collections.binarySearch(nums, 30);System.out.println("30的索引:" + index); // 2(找到)int index2 = Collections.binarySearch(nums, 25);System.out.println("25的索引(未找到):" + index2); // -3(负数表示插入点)// 2. 查找子列表List<String> list = new ArrayList<>();list.add("A");list.add("B");list.add("C");list.add("B");list.add("C");List<String> subList = new ArrayList<>();subList.add("B");subList.add("C");int first = Collections.indexOfSubList(list, subList);int last = Collections.lastIndexOfSubList(list, subList);System.out.println("子列表首次出现索引:" + first); // 1System.out.println("子列表最后出现索引:" + last); // 3// 3. 替换元素boolean replaced = Collections.replaceAll(list, "B", "X");System.out.println("是否替换成功:" + replaced); // trueSystem.out.println("替换后列表:" + list); // [A, X, C, X, C]// 4. 查找最大/最小值List<Integer> maxMinList = new ArrayList<>();maxMinList.add(5);maxMinList.add(2);maxMinList.add(8);int max = Collections.max(maxMinList);int min = Collections.min(maxMinList);System.out.println("最大值:" + max); // 8System.out.println("最小值:" + min); // 2}
}
3. 同步控制(返回线程安全集合)

Java 集合框架中的大部分实现类(如 ArrayListHashMap)都是非线程安全的(多线程并发修改可能导致异常)。Collections 提供了将非线程安全集合转换为线程安全集合的方法,内部通过加锁实现同步。

方法声明功能描述
static <T> Collection<T> synchronizedCollection(Collection<T> c)返回线程安全的 Collection
static <T> List<T> synchronizedList(List<T> list)返回线程安全的 List
static <T> Set<T> synchronizedSet(Set<T> s)返回线程安全的 Set
static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)返回线程安全的 SortedSet
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)返回线程安全的 Map
static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)返回线程安全的 SortedMap

代码示例:线程安全集合

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;public class CollectionsSynchronizedDemo {public static void main(String[] args) {// 非线程安全的ListList<String> unsafeList = new ArrayList<>();// 转换为线程安全的ListList<String> safeList = Collections.synchronizedList(unsafeList);// 非线程安全的MapMap<String, Integer> unsafeMap = new HashMap<>();// 转换为线程安全的MapMap<String, Integer> safeMap = Collections.synchronizedMap(unsafeMap);// 线程安全集合的使用方式与原集合一致safeList.add("Java");safeMap.put("Score", 90);System.out.println("安全List:" + safeList); // [Java]System.out.println("安全Map:" + safeMap); // {Score=90}}
}

注意

  • 线程安全集合仅保证单个方法的原子性,复合操作(如“检查再更新”)仍需手动加锁。
  • 性能较低,高并发场景推荐使用 java.util.concurrent 包下的并发集合(如 ConcurrentHashMapCopyOnWriteArrayList)。
4. 不可修改集合(只读集合)

通过 Collections 可以创建不可修改的集合(只读),任何修改操作(如 addremoveput)都会抛出 UnsupportedOperationException,用于保护集合数据不被篡改。

方法声明功能描述
static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c)返回不可修改的 Collection
static <T> List<T> unmodifiableList(List<? extends T> list)返回不可修改的 List
static <T> Set<T> unmodifiableSet(Set<? extends T> s)返回不可修改的 Set
static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)返回不可修改的 SortedSet
static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)返回不可修改的 Map
static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> m)返回不可修改的 SortedMap

代码示例:不可修改集合

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;public class CollectionsUnmodifiableDemo {public static void main(String[] args) {// 原始可修改集合List<String> mutableList = new ArrayList<>();mutableList.add("A");mutableList.add("B");// 创建不可修改的List(只读)List<String> unmodList = Collections.unmodifiableList(mutableList);System.out.println("只读List:" + unmodList); // [A, B]// 尝试修改只读集合(抛出异常)try {unmodList.add("C"); // 编译通过,运行时抛异常} catch (UnsupportedOperationException e) {System.out.println("错误:" + e.getMessage()); // 不支持的操作}// 原始集合修改,只读集合也会变化(只读集合是原始集合的视图)mutableList.add("C");System.out.println("原始集合修改后,只读List:" + unmodList); // [A, B, C]// 不可修改的Map示例Map<String, Integer> mutableMap = new HashMap<>();mutableMap.put("One", 1);Map<String, Integer> unmodMap = Collections.unmodifiableMap(mutableMap);try {unmodMap.put("Two", 2); // 抛异常} catch (UnsupportedOperationException e) {System.out.println("Map修改错误:" + e.getMessage());}}
}

注意

  • 不可修改集合是原始集合的视图,若原始集合被修改,只读集合也会同步变化。
  • 若需完全独立的只读集合,需先创建副本(如 new ArrayList<>(original)),再转为只读。
5. 空集合(空的不可修改集合)

Collections 提供了预定义的空集合(空列表、空集、空映射),用于避免返回 null(更安全,减少 NullPointerException)。

方法声明功能描述
static <T> List<T> emptyList()返回空的不可修改 List(泛型)
static <T> Set<T> emptySet()返回空的不可修改 Set(泛型)
static <K,V> Map<K,V> emptyMap()返回空的不可修改 Map(泛型)

代码示例:空集合

import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.Collections;public class CollectionsEmptyDemo {public static void main(String[] args) {// 获取空集合(不可修改)List<String> emptyList = Collections.emptyList();Set<Integer> emptySet = Collections.emptySet();Map<String, Double> emptyMap = Collections.emptyMap();System.out.println("空List大小:" + emptyList.size()); // 0System.out.println("空Set是否为空:" + emptySet.isEmpty()); // true// 尝试修改空集合(抛异常)try {emptyList.add("test");} catch (UnsupportedOperationException e) {System.out.println("空集合修改错误:" + e.getMessage());}// 实际应用:方法返回空集合而非nullList<String> result = getData();System.out.println("方法返回的集合大小:" + result.size()); // 0(避免NPE)}// 模拟查询数据,无结果时返回空集合而非nullpublic static List<String> getData() {// 假设查询无结果return Collections.emptyList(); // 比return null更安全}
}
6. 其他实用方法
方法声明功能描述
static <T> boolean addAll(Collection<? super T> c, T... elements)向集合 c 中添加多个元素(可变参数)
static int frequency(Collection<?> c, Object o)统计元素 o 在集合 c 中出现的次数
static boolean disjoint(Collection<?> c1, Collection<?> c2)判断两个集合是否无交集(无共同元素)

代码示例:其他方法

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class CollectionsOtherDemo {public static void main(String[] args) {// 1. 批量添加元素List<String> list = new ArrayList<>();Collections.addAll(list, "Java", "Python", "C++", "Java");System.out.println("批量添加后:" + list); // [Java, Python, C++, Java]// 2. 统计元素出现次数int count = Collections.frequency(list, "Java");System.out.println("Java出现次数:" + count); // 2// 3. 判断集合是否无交集List<Integer> list1 = new ArrayList<>();list1.add(1);list1.add(2);List<Integer> list2 = new ArrayList<>();list2.add(3);list2.add(4);List<Integer> list3 = new ArrayList<>();list3.add(2);list3.add(5);boolean isDisjoint1 = Collections.disjoint(list1, list2);boolean isDisjoint2 = Collections.disjoint(list1, list3);System.out.println("list1与list2无交集:" + isDisjoint1); // true(无共同元素)System.out.println("list1与list3无交集:" + isDisjoint2); // false(有共同元素2)}
}

三、CollectionsArrays 的区别

  • Collections:操作集合对象ListSetMap 等)。
  • Arrays:操作数组(如数组排序 Arrays.sort()、数组转集合 Arrays.asList() 等)。

两者均为工具类,方法均为静态,分别处理集合和数组的常见操作。

四、最佳实践

  1. 避免返回 null:方法返回集合时,若无数据,返回 Collections.emptyList() 等空集合,而非 null,减少 NullPointerException
  2. 线程安全选择:简单线程安全场景可用 synchronizedList() 等,但高并发推荐 java.util.concurrent 包下的集合。
  3. 不可修改保护:当需要传递集合但不允许修改时,使用 unmodifiableList() 等包装,保护数据完整性。
  4. 排序前检查:使用 binarySearch() 前必须确保集合已排序,否则结果不可靠。

总结

Collections 工具类是 Java 集合操作的“瑞士军刀”,提供了排序、查找、同步化、不可修改化等实用功能,极大简化了集合处理代码。掌握其核心方法,能显著提高开发效率,同时保证代码的安全性和可读性。实际开发中,需根据场景灵活选择合适的方法,尤其注意线程安全和不可修改集合的特性。

如需巩固本文内容,可点击以下链接完成相关练习:点击此处进入练习题。

http://www.dtcms.com/a/317805.html

相关文章:

  • Solidity:接口与实现的“契约”关系研究,以Uniswap V3为例
  • 《算法导论》第 6 章 - 堆排序
  • MCP-PromptX AI小说创作使用教程
  • Linux(17)——Linux进程信号
  • C++ STL--> vector的模拟实现!
  • smart-water表设计方案
  • jdk-24的安装及环境变量配置
  • LazyLLM教程 | 第3讲:大模型怎么玩:用LazyLLM带你理解调用逻辑与Prompt魔法!
  • 【前端开发】四. JS内置函数
  • 芯片封装(DIP、SOP、QFP、QFN、BGA、LGA、PGA)
  • C++音视频流媒体开发面试题:音视频基础
  • OceanBase DBA实战营2期--自动分区分裂学习笔记
  • 机器翻译:语料库的定义与获取,及语料预处理
  • 安宝特方案丨工业AR+AI质检方案:致力于提升检测精度与流程效率
  • 无人机航拍数据集|第6期 无人机垃圾目标检测YOLO数据集772张yolov11/yolov8/yolov5可训练
  • LeetCode 分类刷题:611. 有效三角形的个数
  • 阿里云 Flink
  • 稀土新贵醋酸镥:高纯度材料的科技密码
  • 机器人定位装配的精度革命:迁移科技如何重塑工业生产价值
  • [特殊字符]企业游学 | 探秘字节,解锁AI科技新密码
  • 智慧养老破局:科技如何让“老有所养”变成“老有优养”?
  • 加载量化模型
  • 7.3 I/O方式 (答案见原书 P315)
  • HashMap 与 ConcurrentHashMap 深度解析
  • Java Stream (二)
  • 【模电笔记】—— 直流稳压电源——稳压电路
  • 从“T+1”到“T+0”:基于SQL构建MES到数据仓库的数据采集通道
  • 嵌入式学习---在 Linux 下的 C 语言学习 Day9
  • 时隔六年!OpenAI 首发 GPT-OSS 120B / 20B 开源模型:性能、安全与授权细节全解
  • PDW分选如何展示到界面上