Java 12 добавляет новый коллектор в свою библиотеку – teeing collector. Этот коллектор принимает два других коллектора в качестве источников значений стрима, и функцию мержа, в которую он передаёт значения из указанных выше коллекторов.

Визуально схему работы teeing коллектора можно изобразить следующим образом:

Схема работы teeing коллектора

Кстати, слово teeing переводится как «тройной», «тройниковый», «T-образный», что отражает суть работы коллектора – принять два значения, произвести некоторые операции над ними и выдать третье, результирующее значение.

Давайте рассмотрим следующий пример по вычислению среднеарифметического значения набора чисел:

double average = Stream.of(1, 4, 2, 7, 4, 6, 5)
        .collect(teeing(
                summingDouble(i -> i),
                counting(),
                (sum, n) -> sum / n));
System.out.println("Среднее значение ряда: " + average);

Примечание: здесь teeing, summingDouble и counting – статически импортированные методы класса Collectors.

Что же происходит в данном коде?
С помощью summingDoubles коллектора суммируются все значения:

summingDouble(i -> i)

а с помощью counting коллектора подсчитывается количество элементов в стриме:

counting()

После того, как два коллектора выдали результат своих вычислений, teeing коллектор использует переданную функцию, чтобы вычислить среднеарифметическое значение:

(sum, n) -> sum / n)

После этого teeing коллектор возвратит результат:

Среднее значение ряда: 4.142857142857143

Таким образом, teeing коллектор полезен в тех случаях, когда вам требуется распараллелить стрим на два коллектора и затем смержить промежуточные значения в какое-то одно.

Teeing collector в Java 12

Полный исходный код примера:

import java.util.stream.Stream;

import static java.util.stream.Collectors.*;

public class TeeingCollector {
    public static void main(String[] args) {
        double average = Stream.of(1, 4, 2, 7, 4, 6, 5)
                .collect(teeing(
                        summingDouble(i -> i),
                        counting(),
                        (sum, n) -> sum / n));
        System.out.println("Среднее значение ряда: " + average);
    }
}

Collectors.teeing() – новый коллектор в Java 12