Java Stream –减少操作并减少方法

时间:2020-01-09 10:35:15  来源:igfitidea点击:

在这篇文章中,我们将看到Java Stream API中的还原操作以及如何使用通用的还原操作Stream.reduce()方法。

Java Stream中的归约运算

在Java Stream API中,有许多终端操作(例如平均值,总和,最小值,最大值和计数),它们通过组合流的内容来返回一个值。这些操作称为归约操作。

例如,使用减少计数操作对列表中的元素数进行计数。

List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  
long count = myList.stream().count();
System.out.println("Count of elements in the list- " + count);

输出:

Count of elements in the list- 10

减少Java Stream中的方法

Java Stream API还具有通用的reduce方法,该方法使用传递的累加器对流的元素执行约简操作,并返回约简值。 Reduce方法已重载,并具有3个变体。

  1. Optional <T> reduce(BinaryOperator <T>累加器)–使用关联累加函数对该流的元素执行归约,并返回一个Optional描述缩减值(如果有)。

累加器的类型为BinaryOperator,它是一个功能接口,表示对两个相同类型的操作数的操作。累加器函数具有两个参数:约简的部分结果和流的下一个元素。

带有累加器示例的Stream.reduce()

假设有一个Employee类,其中包含name,dept,salary字段。我们需要使用Stream.reduce()方法找出总薪水。

public class Employee {
  private String name;
  private String dept;
  private int salary;

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

通过传递一个累加器函数来使用reduce方法,该函数在本示例中是一个lambda表达式,该函数将两个Integer值相加并返回一个Integer值,我们可以获得总工资。

List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("Hyman", "Finance", 5500));
employeeList.add(new Employee("Lisa", "Accounts", 5600));
employeeList.add(new Employee("Nikita", "IT", 4500));
employeeList.add(new Employee("Tony", "HR", 8000));
Optional<Integer> totalSalary = employeeList.stream().map(e -> e.getSalary()).reduce((a,b) -> a+b);
if(totalSalary.isPresent()){
  System.out.println("Total Salary- " + totalSalary.get());
}

输出:

Total Salary- 23600
  1. reduce(T标识,BinaryOperator <T>累加器)–使用提供的标识值和关联的累加函数对该流的元素执行精简,并返回精简后的值。
  • identity –如果流中没有元素,则identity元素既是reduce的初始值,又是默认结果。
  • 累加器-累加器功能是BinaryOperator的实现,它是一个功能接口,表示对两个相同类型的操作数的操作。累加器函数有两个参数:减少的部分结果和流的下一个元素

带身份和累加器的Stream.reduce()示例

我们可以使用与上面相同的示例,只是reduce方法中有变化,该方法现在还传递一个标识元素0。这是工资总和的初始值,如果集合employeeList中没有成员,则为默认值。
现在reduce方法的返回类型也是int。

List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("Hyman", "Finance", 5500));
employeeList.add(new Employee("Lisa", "Accounts", 5600));
employeeList.add(new Employee("Nikita", "IT", 4500));
employeeList.add(new Employee("Tony", "HR", 8000));
int totalSalary = employeeList.stream().map(e -> e.getSalary()).reduce(0, (a,b) -> a+b);
System.out.println("Total Salary- " + totalSalary);
  1. reduce(U标识,BiFunction <U 、?超级T,U>累加器,BinaryOperator <U>组合器)–使用提供的标识,累加和组合函数对流的元素进行归约。

合并器功能用于合并累加器功能的结果,它必须与累加器功能兼容。当使用并行流以合并并行运行的累加器的结果时,合并器功能是必需的。

带有身份,累加器和合并器的Stream.reduce()示例

int value = Stream.of(1, 2, 3, 4, 5).parallel().reduce(1, (a, b) -> a*b, 
				(x,y) -> { System.out.println("In combiner function");
				           return x*y;});
System.out.println("Value- " + value);

输出:

In combiner function
In combiner function
In combiner function
In combiner function
Value- 120