Java Stream reduce 教程展示了如何对 Java 8 Stream执行缩减操作。
Java Stream 是来自支持聚合操作的源的元素序列。Stream不存储元素;元素是按需计算的。从集合、数组或 I/O 资源等数据源中使用元素。
减少 是一种终端操作,它将Stream聚合为类型或基元。 Java 8 Stream API 包含一组预定义的缩减操作,例如 average
、sum
、min< /code>、max 和 count,它们通过组合Stream的元素返回一个值。
Stream.reduce
是一种用于生成自定义归约操作的通用方法。
Optional<T> reduce(BinaryOperator<T> accumulator)
此方法使用关联累加函数对该Stream的元素执行归约。它返回一个 Optional
描述减少的值,如果有的话。
T reduce(T identity, BinaryOperator<T> accumulator)
该方法有两个参数:标识和累加器。如果Stream中没有元素,标识元素既是缩减的初始值,也是默认结果。累加器函数有两个参数:归约的部分结果和Stream的下一个元素。它返回一个新的部分结果。 Stream.reduce
方法返回缩减的结果。
以下示例使用两个预定义的缩减操作。
JavaReduceEx.java
package com.zetcode; import java.util.Arrays; public class JavaReduceEx { public static void main(String[] args) { int vals[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; int sum = Arrays.stream(vals).sum(); System.out.printf("The sum of values: %d%n", sum); long n = Arrays.stream(vals).count(); System.out.printf("The number of values: %d%n", n); } }
我们有一个整数数组。我们使用 Arrays.stream
从数组创建一个Stream,并执行两个缩减:sum
和 count。
The sum of values: 72 The number of values: 8
带有一个参数的 reduce
方法返回一个 Optional
,这是一个用于空安全的 Java 类。
Car.java
package com.zetcode; public class Car { private final String name; private final int price; public Car(String name, int price) { this.name = name; this.price = price; } public int getPrice() { return price; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Car{name=").append(name).append(", price=") .append(price).append("}"); return builder.toString(); } }
这是 Car
类。
JavaReduceEx2.java
package com.zetcode; import java.util.Arrays; import java.util.List; import java.util.Optional; public class JavaReduceEx2 { public static void main(String[] args) { List<Car> persons = Arrays.asList(new Car("Skoda", 18544), new Car("Volvo", 22344), new Car("Fiat", 23650), new Car("Renault", 19700)); Optional<Car> car = persons.stream().reduce((c1, c2) -> c1.getPrice() > c2.getPrice() ? c1 : c2); car.ifPresent(System.out::println); } }
该示例创建了一个汽车对象列表。我们计算最昂贵的汽车。
Optional<Car> car = persons.stream().reduce((c1, c2) -> c1.getPrice() > c2.getPrice() ? c1 : c2);
从列表中,我们创建一个Stream; reduce
方法的累加器比较汽车的价格并返回较贵的汽车。
car.ifPresent(System.out::println);
如果返回的减少值不为空,我们将其打印到控制台。
Car{name=Fiat, price=23650}
下一个示例添加了其他用例。
MyUtil.java
package com.zetcode; public class MyUtil { public static int add2Ints(int num1, int num2) { return num1 + num2; } }
这是 MyUtil
类,它有一个将两个整数相加的方法。
JavaReduceEx3.java
package com.zetcode; import java.util.stream.IntStream; public class JavaReduceEx3 { public static void main(String[] args) { IntStream.range(1, 10).reduce((x, y) -> x + y) .ifPresent(s -> System.out.println(s)); IntStream.range(1, 10).reduce(Integer::sum) .ifPresent(s -> System.out.println(s)); IntStream.range(1, 10).reduce(MyUtil::add2Ints) .ifPresent(s -> System.out.println(s)); } }
我们创建三个不同的累加器函数来计算 1..10 值的总和。
IntStream.range(1, 10).reduce((x, y) -> x + y).ifPresent(s -> System.out.println(s));
在第一种情况下,我们使用 lambda 表达式进行加法运算。
IntStream.range(1, 10).reduce(Integer::sum).ifPresent(s -> System.out.println(s));
第二种情况使用内置的 Integer::sum
方法。
IntStream.range(1, 10).reduce(MyUtil::add2Ints).ifPresent(s -> System.out.println(s));
最后,我们有一个自定义的添加方法。
正如我们已经提到的,标识既是缩减的初始值,也是Stream中没有元素时的默认结果。
User.java
package com.zetcode; import java.time.LocalDate; import java.time.chrono.IsoChronology; public class User { private String name; private LocalDate dateOfBirth; public User(String name, LocalDate dateOfBirth) { this.name = name; this.dateOfBirth = dateOfBirth; } public String getName() { return name; } public void setName(String name) { this.name = name; } public LocalDate getDateOfBirth() { return dateOfBirth; } public void setDateOfBirth(LocalDate dateOfBirth) { this.dateOfBirth = dateOfBirth; } public int getAge() { return dateOfBirth.until(IsoChronology.INSTANCE.dateNow()) .getYears(); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("User{name=").append(name).append(", dateOfBirth=") .append(dateOfBirth).append("}"); return builder.toString(); } }
这是 User
类。除了通常的属性和 getter 和 setter 之外,我们还有 getAge
方法,它使用 Java 8 日期 API 返回用户的年龄。
JavaReduceEx4.java
package com.zetcode; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; public class JavaReduceEx4 { public static void main(String[] args) { List<User> users = new ArrayList<>(); users.add(new User("Frank", LocalDate.of(1979, 11, 23))); users.add(new User("Peter", LocalDate.of(1985, 1, 18))); users.add(new User("Lucy", LocalDate.of(2002, 5, 14))); users.add(new User("Albert", LocalDate.of(1996, 8, 30))); users.add(new User("Frank", LocalDate.of(1967, 10, 6))); int maxAge = users.stream().mapToInt(User::getAge) .reduce(0, (a1, a2) -> a1 > a2 ? a1 : a2); System.out.printf("The oldest user's age: %s%n", maxAge); } }
在示例中,我们创建了一个用户列表。该示例计算最老用户的年龄。
int maxAge = users.stream().mapToInt(User::getAge) .reduce(0, (a1, a2) -> a1 > a2 ? a1 : a2);
我们从列表中创建一个 Java 8 Stream。使用 mapToInt
方法将Stream映射到 IntStream
。最后,reduce
方法提供了一个标识值(0)和一个累加器;累加器比较年龄值并返回较大的一个。
在本文中,我们使用了 Java Stream 缩减操作。
List 所有 Java 教程.
地址:https://www.cundage.com/article/java-streamreduce.html