推荐使用 Stream.max() 而非 Collectors.maxBy(),如 Optional top = students.stream().max(Comparator.comparing(Student::getScore));它语义更清晰、写法更简洁,性能无差异。

直接用 Collectors.maxBy() 配合 Comparator.comparing(),就能在流中找出按某字段值最大的那个对象,前提是该字段可比较且流非空。
基本写法:指定字段提取并比较
假设有一个学生类 Student,含 name 和 score 字段,要找最高分的学生:
Optional<student> topStudent = students.stream()
.collect(Collectors.maxBy(Comparator.comparing(Student::getScore)));
</student>
这里 comparing(Student::getScore) 自动推导 Integer 的自然序,返回 Optional —— 因为流可能为空,必须安全解包。
处理空流或 null 值的常见方式
- 用
orElse(null)或orElseThrow()明确空值策略 - 若
score可能为null,改用comparing(Student::getScore, Comparator.nullsLast(Comparator.naturalOrder())) - 避免在
comparing的方法引用中抛出异常(如 getter 返回 null 且字段类型不支持 null 比较)
扩展:多级排序后取最大
比如分数相同时,按姓名字典序升序,再取“最大”(即高分优先,同分时姓名靠后的排前面):
Optional<student> top = students.stream()
.collect(Collectors.maxBy(
Comparator.comparing(Student::getScore)
.thenComparing(Student::getName, Comparator.reverseOrder())
));
</student>
注意 maxBy 仍只返回一个结果,它按整个复合比较器选出“最大”的那个元素。
替代方案:用 max() 更简洁(推荐)
其实无需 collect,直接调用终端操作更直观:
Optional<student> top = students.stream()
.max(Comparator.comparing(Student::getScore));
</student>
语义更清晰,性能无差异,且省去 collector 的冗余包装。除非你已在用 collect() 做其他聚合,否则优先选 max()。










