Collections.min/max可配合自定义Comparator快速获取集合极值,推荐Lambda表达式,需注意null安全、避免溢出、优先过滤null,并支持Comparator链式组合;仅适用于非空Collection。

Java 中 Collections.min 和 Collections.max 可以配合自定义 Comparator 快速找出集合中的最小值或最大值,无需手动遍历。关键在于提供符合逻辑的比较器,尤其要注意 null 安全和自然顺序一致性。
使用匿名内部类或 Lambda 表达式传入 Comparator
最常用的方式是直接在方法调用时传入一个比较器。Lambda 更简洁,推荐优先使用:
List<String> words = Arrays.asList("apple", "banana", "cherry");
// 找最长字符串
String longest = Collections.max(words, (s1, s2) -> s1.length() - s2.length());
<p>// 找按忽略大小写的字典序最小字符串
String minIgnoreCase = Collections.min(words, String.CASE_INSENSITIVE_ORDER);
- Lambda 形式:
(a, b) -> Integer.compare(a.xxx(), b.xxx())是安全写法,避免整数溢出(比如用减法可能越界) - 可复用已有比较器,如
String.CASE_INSENSITIVE_ORDER、Comparator.naturalOrder()、Comparator.reverseOrder() - 若元素本身实现
Comparable,但想按其他字段比较,必须显式传 Comparator,否则走自然排序
处理 null 元素要主动防御
默认情况下,Collections.min/max 遇到 null 会抛 NullPointerException。需用 Comparator.nullsFirst() 或 Comparator.nullsLast() 显式指定策略:
List<Integer> numbers = Arrays.asList(3, null, 1, null, 5);
// null 排在最前,最小值为 null;若想跳过 null,应先过滤
Integer minNonNull = Collections.min(
numbers.stream().filter(Objects::nonNull).collect(Collectors.toList()),
Integer::compareTo
);
- 不建议依赖
nullsFirst来“找 null 极值”,业务上通常需明确是否允许 null 参与比较 - 更稳妥的做法是提前过滤掉 null,再调用 min/max,语义更清晰
- 若数据源不可控,可在 Comparator 中用
Objects.equals和空值判断做兜底
对自定义对象按特定字段取极值
假设有一个 Person 类,想按年龄找最年长者:
立即学习“Java免费学习笔记(深入)”;
class Person {
String name;
int age;
Person(String name, int age) { this.name = name; this.age = age; }
}
<p>List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);</p><p>Person oldest = Collections.max(people, Comparator.comparingInt(p -> p.age));
// 或写成方法引用:Comparator.comparingInt(Person::getAge),前提是 age 有 getter
-
Comparator.comparingXXX系列静态方法(如comparingInt、comparing)极大简化代码 - 支持链式调用,例如先按年龄降序,年龄相同时按姓名升序:
comparingInt(Person::getAge).reversed().thenComparing(Person::getName) - 确保所访问字段不会在比较过程中抛异常(如 NPE、空指针调用 getter)
注意 Collections.min/max 的限制
这两个方法只适用于 Collection,不支持数组或 Stream。且要求集合非空,否则抛 NoSuchElementException:
- 对数组:先转为 List,如
Arrays.asList(arr)(注意基本类型数组不适用,需用包装类) - 对 Stream:用
stream.min(comparator)或stream.max(comparator),返回Optional - 务必检查集合是否为空,或用 try-catch,或改用 Optional 版本(Stream API)避免运行时异常


















