前言:
Collectors#teeing :返回一个由两个下游收集器组成的收集器。传递给生成的收集器的每个元素都由下游收集器处理,然后使用指定的合并函数将它们的结果合并到最终结果中。
简单地说,它允许使用两个独立的收集器收集流,然后使用提供的双功能合并结果。
//方法相应参数 函数等。
static <T, R1, R2, R> Collector<T, ?, R> teeing (Collector<? super T, ?, R1> downstream1, Collector<? super T, ?, R2> downstream2, BiFunction<? super R1, ? super R2, R> merger)
举几个栗子:
//vo
class Guest {
private String name; //姓名
private boolean participating;//是否参加
private Integer participantsNumber; //参与人数
public Guest(String name, boolean participating,
Integer participantsNumber) {
this.name = name;
this.participating = participating;
this.participantsNumber = participantsNumber;
}
public boolean isParticipating() {
return participating;
}
public Integer getParticipantsNumber() {
return participantsNumber;
}
}
class EventParticipation {
private List<String> guestNameList;
private Integer totalNumberOfParticipants;
public EventParticipation(List<String> guestNameList,
Integer totalNumberOfParticipants) {
this.guestNameList = guestNameList;
this.totalNumberOfParticipants = totalNumberOfParticipants;
}
@Override
public String toString() {
return "EventParticipation { " +
"guests = " + guestNameList +
", 总参与人数 = " + totalNumberOfParticipants +
" }";
}}
1.统计成功参加的和总人数:
import static java.util.stream.Collectors.*;
var result =
Stream.of(
// Guest(String name, boolean participating, Integer participantsNumber)
new Guest("张三", true, 3),
new Guest("李四", false, 2),
new Guest("王五",true, 6))
.collect(Collectors.teeing(
// 第一个收集器,统计确认参加的
Collectors.filtering(Guest::isParticipating,
//只收集列表中名字的参与者
Collectors.mapping(o -> o.name, Collectors.toList())),
// 第二个收集器,我们需要参与者总数
Collectors.summingInt(Guest::getParticipantsNumber),
//收集器合并到一个新对象中, 值是隐式传递的
EventParticipation::new
));
System.out.println(result);
// 打印结果
// EventParticipation { guests = [张三, 李四],
// 总参加人数 = 11 }
2.筛选两个不同Lists中名称:
//根据过滤器将名称流拆分为两个列表
var result =
Stream.of("Devoxx", "Voxxed Days", "Code One", "Basel One","Angular Connect")
.collect(Collectors.teeing(
// 第一个收集器 过滤包含 xx
Collectors.filtering(n -> n.contains("xx"), Collectors.toList()),
// 第二个收集器 过滤One结尾的
Collectors.filtering(n -> n.endsWith("One"), Collectors.toList()),
// 合并
(List<String> list1, List<String> list2) -> List.of(list1, list2)
));
//执行结果
System.out.println(result); // -> [[Devoxx, Voxxed Days], [Code One, Basel One]]
3.计算并汇总
var result =
Stream.of(5, 12, 19, 21)
.collect(Collectors.teeing(
// 第一个收集器
Collectors.counting(),
// 第二个收集器 求和
Collectors.summingInt(n -> Integer.valueOf(n.toString())),
// 合并输出一个新的对象: (count, sum) -> new Result(count, sum);
Result::new
));
//执行结果
System.out.println(result); // -> {count=4, sum=57}
class Result {
private Long count;
private Integer sum;
public Result(Long count, Integer sum) {
this.count = count;
this.sum = sum;
}
@Override
public String toString() {
return "{" +
"count=" + count +
", sum=" + sum +
'}';
}}
Stream Api#teeing()更多参考:https://dzone.com/articles/java-12-the-teeing-collector