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