Java Stream Collectors.teeing() Examples

In this tutorial we’ll see how to use Collectors.teeing() method which is added in Java 12 to the Collectors class in the Java Stream API.

Collectors.teeing() method

The teeing() method let you create a composite of two Collectors and there is also a third argument; a merging function. Every element passed to the method is processed by both downstream collectors, then their results are merged using the specified merge function into the final result.

Method syntax

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)

Here parameters are-

  • downstream1– the first downstream collector
  • downstream2– the second downstream collector
  • merger– the function which merges two results into the single one

Collectors.teeing() Java examples

1. Getting count and sum of elements in a List using Collectors.teeing function. By passing Collectors.counting() and Collectors.summingInt() as two downstream Collectors you can do the job of both counting the number of elements and getting the sum of elements in a single operation. Merging operation does the job of storing both sum and count in a List and returning that List.

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

public class TeeingDemo {

  public static void main(String[] args) {
     List<Integer> listOfNumbers = Arrays.asList(10, 25, 9, 87, 56);
     List<Integer> list = listOfNumbers.stream()
                          .collect(Collectors.teeing(
                             Collectors.counting(), 
                             Collectors.summingInt(n -> n), 
                             (count, sum) -> {
                                List<Integer> l = new ArrayList<>();
                                l.add(count.intValue());
                                l.add(sum);
                                return l;
                              }));
     System.out.println("Number of elements in the list- " + list.get(0));
     System.out.println("Sum of elements in the list- " + list.get(1));
  }
}

Output

Number of elements in the list- 5
Sum of elements in the list- 187

2. Getting average of elements in a List. Here with in the teeing method first Collector does the job of counting elements, second Collector does the job of getting the sum of elements and the merger operation does the job of calculating average.

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

public class TeeingDemo {

  public static void main(String[] args) {
     List<Integer> listOfNumbers = List.of(10, 25, 9, 87, 56);
     Double average = listOfNumbers.stream()
                        .collect(Collectors.teeing(
                           Collectors.counting(), 
                           Collectors.summingDouble(n -> n), 
                           (count, sum) -> sum/count));
     System.out.println("Average of elements in the list- " + average);
  }
}

Output

Average of elements in the list- 37.4

3. Using Collectors.teeing() to get the employees with the maximum and minimum salaries from the List of Employee objects.
Employee class used is as given below.

public class Employee{
  private String name;
  private String dept;
  private int salary;
  private int age;
  Employee(String name, String dept, int salary, int age){
    this.name = name;
    this.dept = dept;
    this.salary = salary;
    this.age = age;
  }
  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getDept() {
    return dept;
  }
  public void setDept(String dept) {
    this.dept = dept;
  }
  public int getSalary() {
    return salary;
  }
  public void setSalary(int salary) {
    this.salary = salary;
  }
}

To get the maximum and minimum values Collectors.maxBy() and Collectors.minBy() methods are used.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class TeeingDemo {

  public static void main(String[] args) {
    List<Employee> empList =  getEmployeeList();
    List<Optional<Employee>> list = empList.stream()
                       .collect(Collectors.teeing(
                         Collectors.maxBy(Comparator.comparingInt(Employee::getSalary)), 
                         Collectors.minBy(Comparator.comparingInt(Employee::getSalary)), 
                            (emp1, emp2) -> {
                               List<Optional<Employee>> l = new ArrayList<>();
                                 l.add(emp1);
                                 l.add(emp2);
                                 return l;
                            }));
     System.out.println("Employee with max salary- " + (list.get(0).isPresent()? list.get(0).get().getName():null));
     System.out.println("Employee with min salary- " + (list.get(1).isPresent()? list.get(1).get().getName():null));
  }
  
    // Method to create list of employee objects
    private static List<Employee> getEmployeeList(){
        List<Employee> empList = Arrays.asList(new Employee("Ram", "IT", 12000, 34), 
                                       new Employee("Tina", "HR", 15000, 42), 
                                       new Employee("Roger", "IT", 9000, 25), 
                                       new Employee("Troy", "Accounts", 7000, 35));
        
        return empList;
    }
}

Output

Employee with max salary- Tina
Employee with min salary- Troy

Related Posts

That’s all for the topic Java Stream Collectors.teeing() Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Share this post:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.