Java Stream按指定非空日期字段排序的优化实现问询
简化你的对象列表排序逻辑
嘿,你完全不用拆成那么多繁琐步骤来实现这个排序!我们可以通过自定义排序键提取逻辑结合Java的Comparator,一步到位完成符合规则的排序,代码更简洁,性能也更高效。
核心思路拆解
根据你的排序规则,每个obj的排序关键日期可以这样生成:
- 先确定基准日期:如果
date2不为空就用date2,否则直接用非空的date1 - 拿这个基准日期和
date3比,取两者里的较大值作为最终排序键(如果date3是空的或者比基准日期小,就直接用基准日期)
完整实现代码
下面是结合你的Bean代码写的完整示例,包括测试逻辑:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; class obj { private Date date1; private Date date2; private Date date3; obj(Date date1, Date date2, Date date3) { this.date1 = date1; this.date2 = date2; this.date3 = date3; } public Date getDate1() { return date1; } public void setDate1(Date date1) { this.date1 = date1; } public Date getDate2() { return date2; } public void setDate2(Date date2) { this.date2 = date2; } public Date getDate3() { return date3; } public void setDate3(Date date3) { this.date3 = date3; } // 重写toString方便查看排序结果 @Override public String toString() { SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); return String.format("obj(date1=%s, date2=%s, date3=%s)", sdf.format(date1), date2 != null ? sdf.format(date2) : "null", date3 != null ? sdf.format(date3) : "null"); } } public class SortExample { private static Date parseDate(String dateStr) { try { return new SimpleDateFormat("dd/MM/yyyy").parse(dateStr); } catch (ParseException e) { throw new RuntimeException(e); } } public static void main(String[] args) { List<obj> aList = Arrays.asList( new obj(parseDate("1/1/2018"), null, null), new obj(parseDate("4/4/2018"), null, parseDate("6/6/2018")), new obj(parseDate("7/7/2018"), parseDate("8/8/2018"), null) ); // 自定义Comparator,把排序规则直接内嵌进去 Comparator<obj> sortComparator = Comparator.comparing( o -> { // 步骤1:获取基准日期(date2优先,否则用date1) Date baseDate = o.getDate2() != null ? o.getDate2() : o.getDate1(); // 步骤2:取基准日期和date3的较大值作为排序键 return (o.getDate3() != null && o.getDate3().after(baseDate)) ? o.getDate3() : baseDate; } ).reversed(); // 反转排序顺序,实现降序 // 用Stream排序并收集结果 List<obj> sortedList = aList.stream() .sorted(sortComparator) .collect(Collectors.toList()); // 打印排序后的结果 sortedList.forEach(System.out::println); } }
运行结果
执行后会输出符合预期的降序列表:
obj(date1=07/07/2018, date2=08/08/2018, date3=null) obj(date1=04/04/2018, date2=null, date3=06/06/2018) obj(date1=01/01/2018, date2=null, date3=null)
为什么这个方案更好?
- 更高效:避免了多次遍历列表的冗余操作,只需要一次排序遍历,利用Java内置的TimSort算法,性能最优
- 更易维护:所有排序规则都集中在一个
Comparator中,逻辑内聚,可读性强 - 更简洁:不用拆分多个步骤,一行Comparator定义就能搞定核心逻辑
如果你用的是Java 8及以上版本,还可以用Optional让排序键的提取逻辑更优雅:
Comparator<obj> sortComparator = Comparator.comparing( o -> { Date baseDate = Optional.ofNullable(o.getDate2()).orElse(o.getDate1()); return Optional.ofNullable(o.getDate3()) .filter(d -> d.after(baseDate)) .orElse(baseDate); } ).reversed();
内容的提问来源于stack exchange,提问作者Maz
相关产品推荐
相关产品推荐

