使用Comparator对List<Person>排序未达预期,如何按ActiveStatus的time倒序?
问题根因
- 你当前使用的
Comparator.reverseOrder()要求Person类实现了Comparable接口且默认比较逻辑符合你的需求,你的Person类并未实现该接口,也没有关联到ActiveStatus的time字段的比较逻辑,因此排序结果不符合预期。 - 每个
Person对应多条ActiveStatus记录,需要先明确取哪条记录的time作为排序依据,下述方案默认取每个Person的最新状态时间(即status列表中最大的time值)作为排序基准。
代码调整方案
Java 8及以上版本可以直接使用List自带的sort方法结合lambda表达式实现自定义排序,代码如下:
class Business{ List<Person> getActivePersonListInDesc(){ // 原有获取personList的逻辑保持不变 List<Person> personList = ...; // 自定义排序逻辑 personList.sort(Comparator.comparing( (Person person) -> { // 兼容status为null/空的场景 if (person.status == null || person.status.isEmpty()) { return LocalDateTime.MIN; } // 取当前Person最新的状态时间 return person.status.stream() .map(activeStatus -> activeStatus.time) .max(LocalDateTime::compareTo) .orElse(LocalDateTime.MIN); }, // 按时间降序排列 Comparator.reverseOrder() )); return personList; } }
如果你需要使用Collections.sort写法,对应实现如下:
Collections.sort(personList, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { LocalDateTime time1 = getMaxTime(o1); LocalDateTime time2 = getMaxTime(o2); // 降序排序 return time2.compareTo(time1); } private LocalDateTime getMaxTime(Person person) { if (person.status == null || person.status.isEmpty()) { return LocalDateTime.MIN; } return person.status.stream() .map(status -> status.time) .max(LocalDateTime::compareTo) .orElse(LocalDateTime.MIN); } });
适配说明
- 如果需要按最早的状态时间排序,将上述代码中的
max(LocalDateTime::compareTo)改为min(LocalDateTime::compareTo)即可 - 如果需要无状态记录的Person排在最前面,将返回的默认值
LocalDateTime.MIN改为LocalDateTime.MAX - 如果类属性为私有访问权限,需要补充对应的
getStatus()、getTime()getter方法调用,替代直接访问字段的写法
内容的提问来源于stack exchange,提问作者user222
相关产品推荐
相关产品推荐

