Java流 – Java流组合
reduce()操作组合流中的所有元素以产生单个值。
reduce操作采用两个称为种子(初始值)和累加器的参数。
累加器是一个函数。如果流是空的,种子是结果。
种子和一个元素被传递给累加器,它返回部分结果。然后将部分结果和下一个元素传递给累加器函数。
这重复,直到所有元素被传递到累加器。累加器返回的最后一个值是reduce操作的结果。
流相关接口包含两个称为reduce()和collect()的方法来执行通用reduce操作。
诸如sum(),max(),min(),count()等方法在IntStream,LongStream和DoubleStream接口中定义。
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;
}
}
上面的代码生成以下结果。


国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码













