您的位置 首页 java

Java 流组合

reduce()操作组合流中的所有元素以产生单个值。

reduce操作采用两个称为种子(初始值)和 累加器 的参数。

累加器是一个函数。如果流是空的,种子是结果。

种子和一个元素被传递给累加器,它返回部分结果。然后将部分结果和下一个元素传递给累加器函数。

这重复,直到所有元素被传递到累加器。累加器返回的最后一个值是reduce操作的结果。

流相关接口包含两个称为reduce()和collect()的方法来执行通用reduce操作。

诸如sum(),max(),min(),count()等方法在IntStream,LongStream和Double Stream 接口中定义。

count()方法适用于所有类型的流。

Stream<T> 接口包含一个reduce()方法来执行reduce操作。该方法有三个重载版本:

T reduce(T identity, BinaryOperator<T> accumulator)

<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)

Optional<T> reduce(BinaryOperator<T> accumulator)

第一个版本的reduce()方法使用一个标识和一个累加器作为参数,并将流reduce为同一类型的单个值。

import  Java .util.Arrays;
import java.util.List;
public class Main {
 public static void main(String[] args) {
 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
 int sum = numbers.stream()
 .reduce(0, Integer::sum); 
 System.out.println(sum);
 }
}
 

上面的代码生成以下结果。

例2

计算所有员工的收入总和。

import java.time.LocalDate;
import java.time.Month;
import java.util.Arrays;
import java.util.List;
public class Main {
 public static void main(String[] args) {
 double sum = Employee.persons()
 .stream()
 .map(Employee::getIncome)
 .reduce(0.0, Double::sum);
 System.out.println(sum);
 }
}
class Employee {
 public static enum Gender {
 MALE, FEMALE
 }
 private long id;
 private String name;
 private Gender gender;
 private LocalDate dob;
 private double income;
 public Employee(long id, String name, Gender gender, LocalDate dob,
 double income) {
 this.id = id;
 this.name = name;
 this.gender = gender;
 this.dob = dob;
 this.income = income;
 }
 public double getIncome() {
 return income;
 }
 public static List<Employee> persons() {
 Employee p1 = new Employee(1, "Jake", Gender.MALE, LocalDate.of(1971,
 Month.JANUARY, 1), 2343.0);
 Employee p2 = new Employee(2, "Jack", Gender.MALE, LocalDate.of(1972,
 Month.JULY, 21), 7100.0);
 Employee p3 = new Employee(3, "Jane", Gender.FEMALE, LocalDate.of(1973,
 Month. MAY , 29), 5455.0);
 Employee p4 = new Employee(4, "Jode", Gender.MALE, LocalDate.of(1974,
 Month.OCTOBER, 16), 1800.0);
 Employee p5 = new Employee(5, "Jeny", Gender.FEMALE, LocalDate.of(1975,
 Month.DECEMBER, 13), 1234.0);
 Employee  p6  = new Employee(6, "Jason", Gender.MALE, LocalDate.of(1976,
 Month.JUNE, 9), 3211.0);
 List<Employee> persons = Arrays.asList(p1, p2, p3, p4, p5, p6);
 return persons;
 }
}
 

上面的代码生成以下结果。

例3

第二个版本的reduce方法如下所示允许我们执行一个map操作,随后执行reduce操作。

<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
 

第三个参数用于组合部分结果当并行执行缩减操作时。

import java.time.LocalDate;
import java.time.Month;
import java.util.Arrays;
import java.util.List;
public class Main {
 public static void main(String[] args) {
 double sum = Employee.persons()
 .stream()
 .reduce(0.0, (partialSum, person) -> partialSum + person.getIncome(), Double::sum); 
 System.out.println(sum);
 }
}
class Employee {
 public static enum Gender {
 MALE, FEMALE
 }
 private long id;
 private String name;
 private Gender gender;
 private LocalDate dob;
 private double income;
 public Employee(long id, String name, Gender gender, LocalDate dob,
 double income) {
 this.id = id;
 this.name = name;
 this.gender = gender;
 this.dob = dob;
 this.income = income;
 }
 public double getIncome() {
 return income;
 }
 public void setIncome(double income) {
 this.income = income;
 }
 public static List<Employee> persons() {
 Employee p1 = new Employee(1, "Jake", Gender.MALE, LocalDate.of(1971,
 Month.JANUARY, 1), 2343.0);
 Employee p2 = new Employee(2, "Jack", Gender.MALE, LocalDate.of(1972,
 Month.JULY, 21), 7100.0);
 Employee p3 = new Employee(3, "Jane", Gender.FEMALE, LocalDate.of(1973,
 Month.MAY, 29), 5455.0);
 Employee p4 = new Employee(4, "Jode", Gender.MALE, LocalDate.of(1974,
 Month.OCTOBER, 16), 1800.0);
 Employee p5 = new Employee(5, "Jeny", Gender.FEMALE, LocalDate.of(1975,
 Month.DECEMBER, 13), 1234.0);
 Employee p6 = new Employee(6, "Jason", Gender.MALE, LocalDate.of(1976,
 Month.JUNE, 9), 3211.0);
 List<Employee> persons = Arrays.asList(p1, p2, p3, p4, p5, p6);
 return persons;
 }
}
 

上面的代码生成以下结果。

Java流映射并行reduce

Java Streams API支持并行映射缩减操作。

当使用以下reduce方法时,每个线程使用累加器累加部分结果。最后,组合器用于组合来自所有线程的部分结果以获得结果。

<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
 

以下代码显示了如何顺序并行reduce操作工作。

import java.time.LocalDate;
import java.time.Month;
import java.util.Arrays;
import java.util.List;
public class Main {
 public static void main(String[] args) {
 double sum = Employee
 .persons()
 .stream()
 .reduce(
 0.0,
 (Double partialSum, Employee p) -> {
 double accumulated = partialSum + p.getIncome();
 System.out.println(Thread.currentThread().getName()
 + " - Accumulator: partialSum = " + partialSum
 + ", person = " + p + ", accumulated = " + accumulated);
 return accumulated;
 },
 (a, b) -> {
 double combined = a + b;
 System.out.println(Thread.currentThread().getName()
 + " - Combiner: a = " + a + ", b = " + b
 + ", combined = " + combined);
 return combined;
 });
 System.out.println("--------------------------------------");
 System.out.println(sum);
 sum = Employee
 .persons()
 .parallelStream()
 .reduce(
 0.0,
 (Double partialSum, Employee p) -> {
 double accumulated = partialSum + p.getIncome();
 System.out.println(Thread.currentThread().getName()
 + " - Accumulator: partialSum = " + partialSum
 + ", person = " + p + ", accumulated = " + accumulated);
 return accumulated;
 },
 (a, b) -> {
 double combined = a + b;
 System.out.println(Thread.currentThread().getName()
 + " - Combiner: a = " + a + ", b = " + b
 + ", combined = " + combined);
 return combined;
 });
 System.out.println(sum);
 }
}
class Employee {
 public static enum Gender {
 MALE, FEMALE
 }
 private long id;
 private String name;
 private Gender gender;
 private LocalDate dob;
 private double income;
 public Employee(long id, String name, Gender gender, LocalDate dob,
 double income) {
 this.id = id;
 this.name = name;
 this.gender = gender;
 this.dob = dob;
 this.income = income;
 }
 public double getIncome() {
 return income;
 }
 public static List<Employee> persons() {
 Employee p1 = new Employee(1, "Jake", Gender.MALE, LocalDate.of(1971,
 Month.JANUARY, 1), 2343.0);
 Employee p2 = new Employee(2, "Jack", Gender.MALE, LocalDate.of(1972,
 Month.JULY, 21), 7100.0);
 Employee p3 = new Employee(3, "Jane", Gender.FEMALE, LocalDate.of(1973,
 Month.MAY, 29), 5455.0);
 Employee p4 = new Employee(4, "Jode", Gender.MALE, LocalDate.of(1974,
 Month.OCTOBER, 16), 1800.0);
 Employee p5 = new Employee(5, "Jeny", Gender.FEMALE, LocalDate.of(1975,
 Month.DECEMBER, 13), 1234.0);
 Employee p6 = new Employee(6, "Jason", Gender.MALE, LocalDate.of(1976,
 Month.JUNE, 9), 3211.0);
 List<Employee> persons = Arrays.asList(p1, p2, p3, p4, p5, p6);
 return persons;
 }
}
 

上面的代码生成以下结果。

流reduce没有默认值

第三个版本的reduce()如下列方法用于执行没有默认值的缩减操作。

reduce(BinaryOperator<T> accumulator)
 

如果流是空的,我们不能使用默认值为0。

Optional<T>

用于包装结果或不存在结果。

以下代码显示如何计算流中的整数的最大值:

import java.util.Optional;
import java.util.stream.Stream;
public class Main {
 public static void main(String[] args) {
 Optional<Integer> max = Stream.of(1, 2, 3, 4, 5).reduce(Integer::max);
 if (max.isPresent()) {
 System.out.println("max = " + max.get());
 } else {
 System.out.println("max is not defined.");
 }
 
 max = Stream.<Integer> empty().reduce(Integer::max);
 if (max.isPresent()) {
 System.out.println("max = " + max.get());
 } else {
 System.out.println("max is not defined.");
 }
 
 }
}
 

上面的代码生成以下结果。

例5

以下代码打印员工列表中最高收入者的详细信息。

import java.time.LocalDate;
import java.time.Month;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
 public static void main(String[] args) {
 Optional<Employee> person = Employee
 .persons()
 .stream()
 .reduce((p1, p2) -> p1.getIncome() > p2.getIncome() ? p1 : p2);
 if (person.isPresent()) {
 System.out.println("Highest earner: " + person.get());
 } else {
 System.out.println("Could not get the highest earner.");
 }
 }
}
class Employee {
 public static enum Gender {
 MALE, FEMALE
 }
 private long id;
 private String name;
 private Gender gender;
 private LocalDate dob;
 private double income;
 public Employee(long id, String name, Gender gender, LocalDate dob,
 double income) {
 this.id = id;
 this.name = name;
 this.gender = gender;
 this.dob = dob;
 this.income = income;
 }
 public double getIncome() {
 return income;
 }
 public static List<Employee> persons() {
 Employee p1 = new Employee(1, "Jake", Gender.MALE, LocalDate.of(1971,
 Month.JANUARY, 1), 2343.0);
 Employee p2 = new Employee(2, "Jack", Gender.MALE, LocalDate.of(1972,
 Month.JULY, 21), 7100.0);
 Employee p3 = new Employee(3, "Jane", Gender.FEMALE, LocalDate.of(1973,
 Month.MAY, 29), 5455.0);
 Employee p4 = new Employee(4, "Jode", Gender.MALE, LocalDate.of(1974,
 Month.OCTOBER, 16), 1800.0);
 Employee p5 = new Employee(5, "Jeny", Gender.FEMALE, LocalDate.of(1975,
 Month.DECEMBER, 13), 1234.0);
 Employee p6 = new Employee(6, "Jason", Gender.MALE, LocalDate.of(1976,
 Month.JUNE, 9), 3211.0);
 List<Employee> persons = Arrays.asList(p1, p2, p3, p4, p5, p6);
 return persons;
 }
 @Override
 public String toString() {
 String str = String.format("(%s, %s, %s, %s, %.2f)n", id, name, gender,
 dob, income);
 return str;
 }
}
 

上面的代码生成以下结果。

文章来源:智云一二三科技

文章标题:Java 流组合

文章地址:https://www.zhihuclub.com/169225.shtml

关于作者: 智云科技

热门文章

网站地图