Java12 Stream Collectors.teeing()方法详解
学习 Collectors.teeing() 方法(在Java 12中新增),方法语法以及如何在Java中的各种用例中应用teeing()方法。
1.teeing collector的目的
teeing是java.util.stream.Collectors接口中的新静态方法,允许使用两个独立的收集器进行收集,然后使用指定的BiFunction合并结果。
传递给结果收集器的每个元素都由两个下游收集器进行处理,然后使用指定的合并函数将它们的结果合并为最终结果。
请注意,此函数有助于分单个步骤执行特定任务。如果我们不使用teeing()函数,我们可以在两个步骤中执行给定的任务。它只是一种辅助函数,可以帮助减少代码冗余。
2.语法.
/** * downstream1 - 第一个下游收集器 * downstream2 - 第二个下游收集器 * merger - 将两个结果合并成一个单一结果的函数 * returns - 聚合两个提供收集器结果的Collector。 */ public static Collector teeing (Collector downstream1, Collector downstream2, BiFunction merger);
3. 使用 teeing()查找薪水最高的员工和薪水最低的员工
在这个 Collectors.teeing() 示例中,我们有一组员工。我们希望在单个步骤中找出薪水最高的员工和薪水最低的员工。
以下java程序执行查找最大和最小操作,然后将两个项收集到Map中。
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); } }
程序输出:
C:BAMLDFCCUIinstallsjdk-12.0.1bin>java Main.java { MIN=Employee [id=1, name=A, salary=100.0], MAX=Employee [id=4, name=D, salary=400.0] }
这里的Employee类如下所示。
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.使用 teeing() 过滤项目并计算它们
在这个例子中,我们将使用同一组员工。在这里,我们将找到薪水大于200的所有员工,然后我们还会计算这样的员工人数。
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); } }
程序输出:
C:BAMLDFCCUIinstallsjdk-12.0.1bin>java Main.java { count=2, list=[Employee [id=3, name=C, salary=300.0], Employee [id=4, name=D, salary=400.0]] }
5.结论
Collectors.teeing()方法的上述示例非常简单,是为了基本的理解而编写的。您需要非常具体地使用该功能。
简单记住,当您需要执行流操作两次并将结果收集到两个不同的收集器时,请考虑使用teeing()方法。它并不总是适合用例,但在适合时可能会很有用。