Java 8结合Comparator与Optional实现嵌套对象多级排序及空值处理
实现方案
核心思路
Java 8+的Comparator内置了nullsFirst()、nullsLast()方法专门处理空值排序规则,搭配Optional的解包逻辑即可满足需求,同时可以额外处理嵌套对象本身为空的极端场景,避免空指针异常。
代码实现
首先构造排序规则,示例中按要求primaryMarket为空时排末尾,其他字段可根据需求灵活调整空值位置:
// 1. 按primaryMarket排序,空值排末尾 Comparator<AuthorBookStat> sortByPrimaryMarket = Comparator.comparing( a -> Optional.ofNullable(a.getAuthorStats()) .map(AuthorStats::getBookStats) .map(BookStats::getPrimaryMarket) .orElse(null), Comparator.nullsLast(Comparator.naturalOrder()) ); // 2. 按averageBookRatings排序,示例也设置空值排末尾,可按需调整 Comparator<AuthorBookStat> sortByRatings = Comparator.comparing( a -> Optional.ofNullable(a.getAuthorStats()) .map(AuthorStats::getBookStats) .map(BookStats::getAverageBookRatings) .orElse(null), Comparator.nullsLast(Comparator.naturalOrder()) ); // 3. 按pages排序,空值排末尾 Comparator<AuthorBookStat> sortByPages = Comparator.comparing( a -> Optional.ofNullable(a.getAuthorStats()) .map(AuthorStats::getBookStats) .map(BookStats::getPages) .orElse(null), Comparator.nullsLast(Comparator.naturalOrder()) ); // 4. 按genre排序,示例设置空值排前面,可按需调整 Comparator<AuthorBookStat> sortByGenre = Comparator.comparing( a -> Optional.ofNullable(a.getAuthorStats()) .map(AuthorStats::getGenre) .orElse(null), Comparator.nullsFirst(Comparator.naturalOrder()) ); // 执行排序,两种方式都可以 // 方式1:stream排序 var sortedList = authorBookStatList.stream() .sorted(sortByPrimaryMarket .thenComparing(sortByRatings) .thenComparing(sortByPages) .thenComparing(sortByGenre)) .collect(Collectors.toList()); // 方式2:原地排序 // authorBookStatList.sort(sortByPrimaryMarket // .thenComparing(sortByRatings) // .thenComparing(sortByPages) // .thenComparing(sortByGenre));
规则调整说明
- 空值位置调整:需要空值排在序列前就用
Comparator.nullsFirst(),排在末尾就用Comparator.nullsLast() - 排序顺序调整:需要降序排序就把
Comparator.naturalOrder()替换为Comparator.reverseOrder() - 嵌套对象非空校验:如果你的业务逻辑保证
authorStats、bookStats一定不为空,可以去掉外层的Optional.ofNullable包装,直接调用Getter取值即可。
测试后输出结果和预期一致,primaryMarket为null的元素会排在序列最后。
内容的提问来源于stack exchange,提问作者Sandeep Nair
相关产品推荐
相关产品推荐

