public static <T> Collector<T,?,Map<Boolean,List<T>>> partitioningBy(Predicate<? super T> predicate)
分区函数,返回一个map,key永远只有两个分别是boolean值false和true,用法和groupingBy类似。
下面给一个简单的例子:
void test29() {
List<User> userList = List.of((new User("mail1","adr1")),(new User("mail2","a2")),(new User("mail3","adr3")));
Map<Boolean, List<User>> passingFailing = userList.stream().collect(Collectors.partitioningBy(s -> s.getAddr().length() > 2));
passingFailing.forEach((k,v) -> System.out.println(k+" : "+v.stream().collect(Collectors.mapping(a -> a.getEmail()+":"+a.getAddr(), Collectors.toList()))));
}
运行结果:
false : [mail2:a2]
true : [mail1:adr1, mail3:adr3]
严格来说partitioningBy和gourpingBy还是不一样,前者就像是后者的极品版本。首先前者返回的map中只有两个键值对,分别是key为false和true,而对应的value是集合中不满足和满足partitioningBy函参条件的元素集合。
public static <T,D,A> Collector<T,?,Map<Boolean,D>> partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream)
两个参数的partitioningBy方法,相比上面的方法多了一个Collector类型的downstream参数,作用不言而喻,就是减少中间数据处理步骤,能直接一步得到想要的结果。
看个例子:
void test30() {
List<User> userList = List.of((new User("mail1","adr1")),(new User("mail2","a2")),(new User("mail3","adr3")));
Map<Boolean, List<String>> passingFailing = userList.stream().collect(Collectors.partitioningBy(s -> s.getAddr().length() > 2, Collectors.mapping(a -> a.getEmail()+":"+a.getAddr(), Collectors.toList())));
passingFailing.forEach((k,v) -> System.out.println(k+" : "+v));
}
运行结果:
false : [mail2:a2]
true : [mail1:adr1, mail3:adr3]
仔细理解一下上面两个例子,就会发现后面一个例子在结果集中就直接得到了可以直接打印的字符串类型而不是不能直接打印的user对象类型。
还是举个不恰当的例子,假如你要去你家附近的澡堂子洗澡,首先你会先在家换一身去澡堂洗澡的便装,然后走到澡堂在更衣室把便装脱光在进洗浴室开始洗澡,这就是前面一个参数的例子,而第二个2个参数的例子就像是你直接在家里把衣服脱光光然后直接走进澡堂的洗浴室洗澡,一步到位没有中间步骤是不是特别爽。