241. Java 集合 - 使用 Collections 工厂类处理集合

241. Java 集合 - 使用 Collections 工厂类处理集合

Collections 工厂类提供了一组方法来操作集合及其内容,包含了约 70 个方法。在本节中,我们将重点介绍其中的一部分。

🏆 提取集合中的最小值或最大值

Collections 类提供了两个方法 min()max() 来提取集合中的最小值和最大值。你可以通过以下两种方式调用它们:

  1. 不带比较器 :如果没有提供比较器,集合中的元素必须实现 Comparable 接口,否则会抛出 ClassCastException 异常。
  2. 带比较器 :如果提供了一个比较器,min()max() 将使用它来确定最小值或最大值,无论集合元素是否实现 Comparable
示例:获取最小值和最大值
java 复制代码
List<Integer> numbers = List.of(5, 2, 9, 1, 7);
int min = Collections.min(numbers);
int max = Collections.max(numbers);
System.out.println("Min: " + min + ", Max: " + max);

注意

  • 对于空集合,调用 min()max() 方法会抛出 NoSuchMethodException 异常。

🔍 查找列表中的子列表

Collections 类提供了两个方法来查找子列表在更大列表中的位置:

  1. indexOfSublist(List<?> source, List<?> target) :返回目标列表中第一个元素在源列表中的索引。如果目标列表不存在,返回 -1
  2. lastIndexOfSublist(List<?> source, List<?> target):返回目标列表最后一个元素在源列表中的索引。
示例:查找子列表
java 复制代码
List<String> source = List.of("a", "b", "c", "d", "e");
List<String> target = List.of("c", "d");
int index = Collections.indexOfSubList(source, target);
System.out.println("Index of sublist: " + index);

输出

java 复制代码
Index of sublist: 2

🔄 更改列表元素的顺序

Collections 类提供了几个方法来改变列表中元素的顺序:

  1. sort() :按升序排序列表。可以传入一个 Comparator,如果没有,则要求元素必须实现 Comparable 接口。自 Java SE 8 以来,推荐使用 List 接口中的 sort() 方法。
  2. shuffle() :随机打乱列表元素的顺序。可以传入一个 Random 实例,如果需要可重复的随机顺序。
  3. rotate():旋转列表的元素。旋转后,索引 0 的元素将移动到索引 1,依此类推,最后的元素将移动到列表的开头。
示例:旋转列表元素
java 复制代码
List<String> strings = Arrays.asList("0", "1", "2", "3", "4");
System.out.println("Before rotate: " + strings);
Collections.rotate(strings, 1); // 向右旋转
System.out.println("After rotate: " + strings);

输出

java 复制代码
Before rotate: [0, 1, 2, 3, 4]
After rotate: [4, 0, 1, 2, 3]
  1. reverse():反转列表中元素的顺序。
  2. swap():交换列表中的两个元素。
示例:反转列表
java 复制代码
List<String> strings = Arrays.asList("a", "b", "c", "d");
Collections.reverse(strings);
System.out.println("Reversed list: " + strings);

输出

java 复制代码
Reversed list: [d, c, b, a]

🛡️ 包装集合为不可变集合

Collections 工厂类提供了几种方法,用于创建集合的不可变包装器。包装后的集合无法修改,任何修改操作都会抛出异常。重要的是,这些方法返回的是包装器,而不是集合的副本,所以如果原集合被修改,包装器也会反映出这些变化。

这些方法的命名遵循一定规则,通常以 unmodifiable 开头。例如,要创建一个不可变的 List 包装器,你可以使用 unmodifiableList() 方法。

示例:创建不可变列表
java 复制代码
List<String> strings = new ArrayList<>(Arrays.asList("0", "1", "2", "3", "4"));
List<String> immutableStrings = Collections.unmodifiableList(strings);
System.out.println(immutableStrings);
// 下面的代码会抛出 UnsupportedOperationException 异常
immutableStrings.add("5");

输出

java 复制代码
[0, 1, 2, 3, 4]

注意 :如果你修改了原始集合(strings),它也会反映在不可变集合中。这是因为不可变包装器仅仅是原集合的一个视图。


🔒 包装集合为同步集合

和创建不可变集合类似,Collections 工厂类还可以创建同步集合的包装器。同步集合确保在多线程环境下安全访问。

同步集合的命名规则为:synchronized 后跟集合类型名称。例如,要创建同步的 List,你可以使用 synchronizedList() 方法。

示例:创建同步列表
java 复制代码
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>(Arrays.asList("a", "b", "c")));

注意事项

  • 所有对集合的访问必须通过同步包装器进行。
  • 在遍历集合时,使用迭代器或流时,代码需要进行同步操作,以避免竞态条件。

尽管 Collections 提供了同步集合,但 Java.util.concurrent 包中的类通常提供了更好的并发解决方案。


📜 小结

  1. min()max():提取集合中的最小值和最大值,支持使用比较器。
  2. indexOfSubList()lastIndexOfSubList():查找子列表在大列表中的位置。
  3. 排序和顺序操作sort(), shuffle(), rotate(), reverse()swap() 提供了多种操作集合顺序的方法。
  4. 不可变集合包装 :使用 unmodifiable 系列方法创建不可变集合,修改原集合会反映到不可变集合中。
  5. 同步集合包装 :使用 synchronized 系列方法创建同步集合,确保线程安全。

问题 :如何通过 Collections 类创建一个不可变的 List答案 :你可以使用 Collections.unmodifiableList() 方法创建一个不可变的 List,但要小心,如果原始集合被修改,包装器也会反映这些变化。

相关推荐
妙蛙种子3112 分钟前
【Java设计模式 | 创建者模式】 原型模式
java·开发语言·后端·设计模式·原型模式
橘子编程6 分钟前
React 19 全栈开发实战指南
前端·react.js·前端框架
DanCheOo7 分钟前
AI Streaming 架构:从浏览器到服务端的全链路流式设计
前端·agent
阿聪谈架构9 分钟前
第07章(下):LangGraph 工作流进阶 —— 检查点、人工介入与多 Agent 协作
人工智能·后端
我是小趴菜13 分钟前
前端如何让图片、视频、pdf等文件在浏览器直接下载而非预览
前端
希望永不加班14 分钟前
SpringBoot 配置绑定:@ConfigurationProperties
java·spring boot·后端·spring
悟空码字15 分钟前
MySQL性能优化的天花板:10条你必须掌握的顶级SQL分析技巧
java·后端·mysql
cg3317 分钟前
开源项目自动化:用 GitHub Actions 让每个 Issue 都被温柔以待
前端
Soofjan19 分钟前
Go interface 源码:iface、itab、getitab 与动态派发
后端
Soofjan21 分钟前
Go interface:语法、接口值与常见坑
后端