跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

怎么利用 Collections.max() 配合自定义 Comparator 找出身高最高的同学

Collections.max() 直接传入未实现Comparable的Student列表会因无法比较而抛ClassCastException;需用Comparator.comparing(Student::getHeight).reversed()等显式指定比较逻辑,并防护空集合和null字段。 为什么
Collections.max()
直接用会报错 直接传入
List
调用
Collections.max()
会抛出
ClassCastException
或提示 “cannot be cast to java.lang.Comparable”,因为
Student
类默认没实现
Comparable
,Java 不知道怎么比身高。必须显式告诉它:按
height
字段升序/降序比。 用 Lambda 写最简 Comparator 找最高同学 假设
Student
类有
getHeight()
方法(返回
double
或
int
),一行 Lambda 就够:
Student tallest = Collections.max(students, (a, b) -> Double.compare(a.getHeight(), b.getHeight()));
注意这里用
Double.compare()
(或
Integer.compare()
),别用
a.getHeight() - b.getHeight()
—— 浮点减法可能丢失精度,整数相减还可能溢出。 如果
height
是
int
,用
Integer.compare(a.getHeight(), b.getHeight())
想让结果更直观,可改用
Comparator.comparing(Student::getHeight).reversed()
,语义明确且支持链式扩展 输入
students
不能为空,否则抛
NoSuchElementException
,务必提前判空 用方法引用 +
reversed()
避免写反逻辑 有人习惯写
(a, b) -> b.getHeight() - a.getHeight()
来“倒着比”,但易读性差、类型不安全。更稳妥的是正向比较再翻转:
Student tallest = Collections.max(students, Comparator.comparing(Student::getHeight).reversed());
这样即使后续要加二级排序(比如身高相同按姓名排),只需追加
thenComparing(Student::getName)
,不用重写整个比较逻辑。
Comparator.comparing()
自动处理
null
值问题(默认抛
NullPointerException
),如需容忍
null
,得用
comparing(..., Comparator.nullsLast(...))
如果
height
字段是
Double
包装类,确保不是
null
,否则
compareTo()
会 NPE;用
Comparator.nullsLast(Comparator.naturalOrder())
更健壮 别忽略空集合和 null 字段的运行时风险
Collections.max()
对空集合直接炸,而
Student
的
height
如果是包装类型且为
null
,
Comparator.comparing
默认也会炸。生产代码里这两处必须防护: 检查
students
是否为
null
或
isEmpty()
,建议用
Optional.ofNullable(students).filter(list -> !list.isEmpty()).map(...).orElse(null)
若
height
可能为
null
,写成
Comparator.comparing(Student::getHeight, Comparator.nullsLast(Comparator.naturalOrder())).reversed()
不要依赖 IDE 自动生成的
compareTo
——手写时容易漏掉字段非空校验,Lambda 或静态比较器更可控 实际业务中,“最高”常隐含“非 null 身高且集合非空”前提,但这个前提不会自动成立,得靠代码守住。

相关文章