深入理解 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 类提供了多种统计信息的收集器,如 summarizingIntsummarizingLongsummarizingDouble

复制代码
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() 方法。

如果你有任何问题或需要进一步的解释,请随时提问!

相关推荐
每次的天空18 分钟前
移动应用开发:自定义 View 处理大量数据的性能与交互优化方案
android·java·学习·交互
纪元A梦20 分钟前
贪心算法应用:最小反馈顶点集问题详解
java·算法·贪心算法
九转苍翎1 小时前
Java SE(10)——抽象类&接口
java
明月与玄武1 小时前
Spring Boot中的拦截器!
java·spring boot·后端
矢鱼1 小时前
单调栈模版型题目(3)
java·开发语言
n33(NK)1 小时前
Java中的内部类详解
java·开发语言
为美好的生活献上中指1 小时前
java每日精进 5.07【框架之数据权限】
java·开发语言·mysql·spring·spring cloud·数据权限
菲兹园长1 小时前
SpringBoot统一功能处理
java·spring boot·后端
一刀到底2112 小时前
java 多核,多线程,分布式 并发编程的现状 :从本身的jdk ,到 spring ,到其它第三方。
java·分布式·高并发
Kendra9192 小时前
Docker 容器 - Dockerfile
java·docker·eureka