/** * Returns a {@code Collector} that is a composite of two downstream collectors. * Every element passed to the resulting collector is processed by both downstream * collectors, then their results are merged using the specified merge function * into the final result. * * <p>The resulting collector functions do the following: * * <ul> * <li>supplier: creates a result container that contains result containers * obtained by calling each collector's supplier * <li>accumulator: calls each collector's accumulator with its result container * and the input element * <li>combiner: calls each collector's combiner with two result containers * <li>finisher: calls each collector's finisher with its result container, * then calls the supplied merger and returns its result. * </ul> * * <p>The resulting collector is {@link Collector.Characteristics#UNORDERED} if both downstream * collectors are unordered and {@link Collector.Characteristics#CONCURRENT} if both downstream * collectors are concurrent. * * @param <T> the type of the input elements * @param <R1> the result type of the first collector * @param <R2> the result type of the second collector * @param <R> the final result type * @param downstream1 the first downstream collector * @param downstream2 the second downstream collector * @param merger the function which merges two results into the single one * @return a {@code Collector} which aggregates the results of two supplied collectors. * @since 12 */ publicstatic <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) { return teeing0(downstream1, downstream2, merger); }
API 描述重的一句话非常关键:
Every element passed to the resulting collector is processed by both downstream collectors 结合「三通图」来说明就是,集合中每一个要被传入 merger 的元素都会经过 downstream1 和 downstream2 的加工处理
@FunctionalInterface publicinterfaceBiFunction<T, U, R> {
/** * Applies this function to the given arguments. * * @param t the first function argument * @param u the second function argument * @return the function result */ R apply(T t, U u); }
至于可以如何处理,我们来看一些例子吧
例子
为了更好的说明 teeing 的使用,列举了四个例子,看过这四个例子再回看上面的 API 说明,相信你会柳暗花明了
List<Melon> melons = Arrays.asList(new Melon("Crenshaw", 1200), new Melon("Gac", 3000), new Melon("Hemi", 2600), new Melon("Hemi", 1600), new Melon("Gac", 1200), new Melon("Apollo", 2600), new Melon("Horned", 1700), new Melon("Gac", 3000), new Melon("Hemi", 2600) );
@Override public String toString(){ return"EventParticipation { " + "guests = " + guestNameList + ", total number of participants = " + totalNumberOfParticipants + " }"; } }
通过 teeing API 处理
1 2 3 4 5 6 7 8 9 10
var result = Stream.of( new Guest("Marco", true, 3), new Guest("David", false, 2), new Guest("Roger",true, 6)) .collect(Collectors.teeing( Collectors.filtering(Guest::isParticipating, Collectors.mapping(Guest::getName, Collectors.toList())), Collectors.summingInt(Guest::getParticipantsNumber), EventParticipation::new )); System.out.println(result);