Collectors teeing() method examples

Learn about Collectors.teeing() method (added in Java 12), method syntax and how to apply teeing() method in various usecases in Java.

1. Purpose of teeing collector

It is a new static method teeing to java.util.stream.Collectors interface which allows to collect using two independent collectors, then merge their results using the supplied BiFunction.

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.

Please note that this function helps in performing a certain task in single steps. We can already perform the given task in two steps if we do not use the teeing() function. It’s just a helper function which helps in reducing the verbosity.

2. Syntax

/**
* downstream1 - the first downstream collector
* downstream2 - the second downstream collector
* merger - the function which merges two results into the single one

* returns - a Collector which aggregates the results of two supplied collectors.
*/

public static Collector teeing​ (Collector downstream1, 
								Collector downstream2, 
								BiFunction merger);

3. Use teeing() to find max and min salaried employees

In this Collectors.teeing() example, we have a list of employees. We want to find out employee with maximum salary and employee with minimum salary in single step.

The following java program performs finding max and min operations, then collect both items in a Map.

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

public class Main 
{
	public static void main(String[] args) 
	{
		List<Employee> employeeList = Arrays.asList(
										new Employee(1, "A", 100),
										new Employee(2, "B", 200),
										new Employee(3, "C", 300),
										new Employee(4, "D", 400)); 
		
		HashMap<String, Employee> result = employeeList.stream().collect( 
							Collectors.teeing(
									Collectors.maxBy(Comparator.comparing(Employee::getSalary)),
									Collectors.minBy(Comparator.comparing(Employee::getSalary)),
									(e1, e2) -> {
										HashMap<String, Employee> map = new HashMap();
										map.put("MAX", e1.get());
										map.put("MIN", e2.get());
										return map;
									}
							));
		
		System.out.println(result);
	}
}

Program output.

C:\BAML\DFCCUI\installs\jdk-12.0.1\bin>java Main.java

{	
	MIN=Employee [id=1, name=A, salary=100.0], 
	MAX=Employee [id=4, name=D, salary=400.0]
}

Here Employee class is like this.

class Employee 
{
	private long id;
	private String name;
	private double salary;

	public Employee(long id, String name, double salary) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
	}

	//Getters and setters

	@Override
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + "]";
	}
}

4. Use teeing() to filter items and count them

In this example, we will use the same set of employees. Here, we will find all employees with salary greater than 200, and then we will also count the number of such employees.

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

public class Main 
{
	public static void main(String[] args) 
	{
		List<Employee> employeeList = Arrays.asList(
										new Employee(1, "A", 100),
										new Employee(2, "B", 200),
										new Employee(3, "C", 300),
										new Employee(4, "D", 400)); 
		
		HashMap<String, Object> result = employeeList.stream().collect( 
							Collectors.teeing(
									Collectors.filtering(e -> e.getSalary() > 200, Collectors.toList()),
									Collectors.filtering(e -> e.getSalary() > 200, Collectors.counting()),
									(list, count) -> {
										HashMap<String, Object> map = new HashMap();
										map.put("list", list);
										map.put("count", count);
										return map;
									}
							));
		
		System.out.println(result);
	}
}

Program output.

C:\BAML\DFCCUI\installs\jdk-12.0.1\bin>java Main.java

{
	count=2, 
	list=[Employee [id=3, name=C, salary=300.0], Employee [id=4, name=D, salary=400.0]]
}

5. Conclusion

Above examples of Collectors.teeing() method are very simple and written for basic understanding. You need to use the function very specific to your own need.

Simply remember that when you need to perform stream operation twice and collect results in two different collectors, consider using teeing() method. It will not always fit in the usecase, but it may be useful when it fits in.

Happy Learning !!

Reference : Java Doc

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.