319. Java Stream API - 使用终端收集器
在 Java 的 Collector API 中,有一组非常有用的 终端收集器(terminal collectors),它们与 Stream API 中的终端操作紧密对应。下面,我们来逐一讲解这些收集器的作用、使用方式,以及它们在实际开发中的典型应用场景。
🔍 1. maxBy() 和 minBy()
这两个收集器用于找出流中的 最大值或最小值。
它们接收一个 Comparator 作为参数,并返回一个 Optional<T>。如果流为空,那么返回的 Optional 也是空的。
📌 示例:
import java.util.*;
import java.util.stream.*;
public class MaxMinCollectorDemo {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie", "David");
Optional<String> longestName = names.stream()
.collect(Collectors.maxBy(Comparator.comparingInt(String::length)));
Optional<String> shortestName = names.stream()
.collect(Collectors.minBy(Comparator.comparingInt(String::length)));
System.out.println("Longest name: " + longestName.orElse("N/A"));
System.out.println("Shortest name: " + shortestName.orElse("N/A"));
}
}
🎯 输出:
Longest name: Charlie
Shortest name: Bob
➕ 2. summingInt() / summingLong() / summingDouble()
这三个收集器用于对流中的元素进行求和。
你需要传入一个映射函数,将对象映射为 int、long 或 double,然后进行加总。
📌 示例:
record Product(String name, double price) {}
public class SumDemo {
public static void main(String[] args) {
List<Product> products = List.of(
new Product("Pen", 1.5),
new Product("Notebook", 3.0),
new Product("Pencil", 0.5)
);
double totalPrice = products.stream()
.collect(Collectors.summingDouble(Product::price));
System.out.println("Total price: " + totalPrice);
}
}
🎯 输出:
Total price: 5.0
📊 3. averagingInt() / averagingLong() / averagingDouble()
这些收集器用于计算平均值,也接受一个映射函数,将对象映射为对应数值类型。
不同于 IntStream.average() 等方法,这些收集器始终返回一个 Double 值,即使流为空时也不会抛异常,而是返回 0.0。
📌 示例:
public class AverageDemo {
public static void main(String[] args) {
List<String> words = List.of("cat", "elephant", "tiger", "lion");
double averageLength = words.stream()
.collect(Collectors.averagingInt(String::length));
System.out.println("Average length: " + averageLength);
}
}
🎯 输出:
Average length: 5.25
🧠 小贴士:
averagingInt()和IntStream.average()的区别在于:IntStream.average()返回OptionalDouble,如果流为空会返回Optional.empty();Collectors.averagingInt()返回Double类型,并且空流默认返回0.0,更安全。
📌 小结
| 收集器名称 | 功能描述 | 返回类型 | 空流处理方式 |
|---|---|---|---|
maxBy() / minBy() | 获取最大 / 最小元素 | Optional<T> | 返回空 Optional |
summingInt() 等 | 求和 | int / long / double | 返回 0 |
averagingInt() 等 | 求平均值 | Double | 返回 0.0 |
这些收集器在实际开发中非常常见,尤其适用于统计类、报表类、分析类的处理场景。如果你想基于 Stream 结果进行一些汇总、分析操作,这些工具就是你的好帮手!