Java Streams中partitioningBy分区后分别排序列表的实现方法
问题根因
原有代码顺序颠倒的核心原因:partitioningBy按布尔值分组后,直接遍历values()的默认顺序是先返回key为false的分组、再返回key为true的分组,和教育类资源(isEducational=true)在前的需求相反,且直接取values()属于依赖Map内部实现顺序的不可靠写法。
推荐实现:复合比较器单次排序
无需分组、无需二次遍历调整顺序,直接通过多关键字比较规则一次排序完成,性能最优、代码最简洁:
import java.util.Comparator; import java.util.stream.Collectors; import java.util.List; // 省略其他业务代码 List<Resource> sortedResources = resources.stream() .sorted( // 第一排序维度:教育类资源放前面,布尔值倒序即可实现true优先 Comparator.comparing(Resource::isEducational, Comparator.reverseOrder()) // 第二排序维度:同类别内按level升序排列 .thenComparingInt(Resource::getLevel) ) .collect(Collectors.toList());
运行后输出顺序完全匹配预期:
Resource{level=2, identifier='e', isEducational=true} Resource{level=3, identifier='c', isEducational=true} Resource{level=4, identifier='a', isEducational=true} Resource{level=2, identifier='f', isEducational=false} Resource{level=3, identifier='d', isEducational=false} Resource{level=4, identifier='b', isEducational=false}
分组逻辑修正方案
如果需要保留分组分别处理的编码逻辑,不要直接遍历values(),显式指定两个分组的拼接顺序即可,完全规避Map内部遍历顺序的不确定性:
import java.util.function.Function; import java.util.stream.Collectors; import java.util.Map; import java.util.stream.Stream; // 省略其他业务代码 Map<Boolean, List<Resource>> partitioned = resources.stream() .collect(Collectors.partitioningBy(Resource::isEducational)); List<Resource> sortedResources = Stream.of( partitioned.get(true).stream().sorted(Comparator.comparingInt(Resource::getLevel)), partitioned.get(false).stream().sorted(Comparator.comparingInt(Resource::getLevel)) ) .flatMap(Function.identity()) .collect(Collectors.toList());
注:你提供的
Resource类定义存在笔误:构造器声明level参数为String类型,但初始化列表时传入的是int类型字面量,实际运行前请统一level的类型,避免编译错误。
内容的提问来源于stack exchange,提问作者Adhyatmik
相关产品推荐
相关产品推荐

