Close

Java 12 - Composing Collectors with Collectors.teeing()

[Last Updated: Aug 11, 2020]

In Java 12 following new method has been added to java.util.stream.Collectors class:

public 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)

Above method returns a 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.

Examples

package com.logicbig.example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TeeingExample {
  public static void main(String[] args) {
      Collector<CharSequence, ?, String> joiningCollector = Collectors.joining("-");
      Collector<String, ?, List<String>> listCollector = Collectors.toList();
      //returns joined string and individual strings as array
      Collector<String, ?, String[]> compositeCollector = Collectors.teeing(joiningCollector, listCollector,
              (joinedString, strings) -> {
                  ArrayList<String> list = new ArrayList<>(strings);
                  list.add(joinedString);
                  String[] array = list.toArray(new String[0]);
                  return array;
              });

      String[] strings = Stream.of("Apple", "Banana", "Orange").collect(compositeCollector);
      System.out.println(Arrays.toString(strings));
  }
}
[Apple, Banana, Orange, Apple-Banana-Orange]
package com.logicbig.example;

import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

public class TeeingExample2 {
  public static void main(String[] args) {
      Collector<Integer, ?, Long> summing = Collectors.summingLong(Integer::valueOf);
      Collector<Integer, ?, Long> counting = Collectors.counting();

      //example list
      List<Integer> list = List.of(1, 2, 4, 5, 7, 8);

      //collector for  map entry consisting of sum and count
      Collector<Integer, ?, Map.Entry<Long, Long>> sumAndCountMapEntryCollector =
              Collectors.teeing(summing, counting, Map::entry);
      Map.Entry<Long, Long> sumAndCountMap = list.stream().collect(sumAndCountMapEntryCollector);
      System.out.println(sumAndCountMap);

      //collect sum and count as List
      Collector<Integer, ?, List<Long>> sumAndCountListCollector =
              Collectors.teeing(summing, counting, List::of);//(v1, v2) -> List.of(v1, v2)
      List<Long> sumAndCountArray = list.stream().collect(sumAndCountListCollector);
      System.out.println(sumAndCountArray);
  }
}
27=6
[27, 6]

Example Project

Dependencies and Technologies Used:

  • JDK 12
java-12-collectors-changes Select All Download
  • java-12-collectors-changes
    • src
      • com
        • logicbig
          • example
            • TeeingExample.java

    See Also