深入理解 Java 8 Stream 之 collect()
Java 8 引入了 Stream API,提供了一种高效且易于使用的数据处理方式。collect()
方法是 Stream API 中一个非常强大的工具,用于将流中的元素收集到集合或其他容器中。本文将详细介绍 collect()
方法的基础用法及各种高阶用法。
基础用法
collect()
方法的基本形式如下:
<R> R collect(Collector<? super T, A, R> collector);
其中:
T
是流中元素的类型。R
是最终结果的类型。A
是累加器的类型,用于中间计算。
最常见的 Collector
实现是 Collectors
类提供的静态方法。下面是一些基础用法的例子。
1. 收集到列表
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> upperCaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upperCaseNames); // 输出: [ALICE, BOB, CHARLIE]
2. 收集到集合
Set<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5).stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toSet());
System.out.println(numbers); // 输出: [2, 4]
3. 收集到字符串
String result = Arrays.asList("a", "b", "c").stream()
.collect(Collectors.joining(", "));
System.out.println(result); // 输出: a, b, c
高阶用法
1. 分组
groupingBy
方法可以将流中的元素按某个属性分组。
List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 25)
);
Map<Integer, List<Person>> peopleByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge));
System.out.println(peopleByAge);
// 输出: {25=[Person{name='Alice', age=25}, Person{name='Charlie', age=25}], 30=[Person{name='Bob', age=30}]}
2. 多级分组
可以使用嵌套的 groupingBy
进行多级分组。
Map<Integer, Map<String, List<Person>>> peopleByAgeAndCity = people.stream()
.collect(Collectors.groupingBy(Person::getAge,
Collectors.groupingBy(Person::getCity)));
System.out.println(peopleByAgeAndCity);
// 输出: {25={New York=[Person{name='Alice', age=25, city='New York'}], Los Angeles=[Person{name='Charlie', age=25, city='Los Angeles'}]}, 30={Chicago=[Person{name='Bob', age=30, city='Chicago'}]}}
3. 分区
partitioningBy
方法可以将流中的元素按布尔条件分成两个部分。
Map<Boolean, List<Person>> adults = people.stream()
.collect(Collectors.partitioningBy(p -> p.getAge() >= 18));
System.out.println(adults);
// 输出: {false=[], true=[Person{name='Alice', age=25}, Person{name='Bob', age=30}, Person{name='Charlie', age=25}]}
4. 自定义收集器
可以使用 Collector.of
方法创建自定义的收集器。
class Person {
private String name;
private int age;
// 构造函数、getter 和 setter 省略
public static Collector<Person, ?, Integer> totalAge() {
return Collector.of(
() -> 0, // 初始化累加器
(sum, person) -> sum + person.getAge(), // 累加函数
(sum1, sum2) -> sum1 + sum2, // 合并函数
sum -> sum // 结果函数
);
}
}
int totalAge = people.stream()
.collect(Person::totalAge);
System.out.println(totalAge); // 输出: 80
5. 统计信息
Collectors
类提供了多种统计信息的收集器,如 summarizingInt
、summarizingLong
和 summarizingDouble
。
IntSummaryStatistics stats = people.stream()
.collect(Collectors.summarizingInt(Person::getAge));
System.out.println(stats); // 输出: IntSummaryStatistics{count=3, sum=80, min=25, average=26.666667, max=30}
总结
collect()
方法是 Java 8 Stream API 中一个非常强大且灵活的工具,它可以用于将流中的元素收集到各种集合中,进行分组、分区、统计等操作。通过 Collectors
类提供的丰富方法,可以轻松实现复杂的数据处理任务。希望本文能帮助你更好地理解和使用 collect()
方法。
如果你有任何问题或需要进一步的解释,请随时提问!