深入理解 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() 方法。

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

相关推荐
MY_TEUCK6 小时前
Sealos 平台部署实战指南:结合 Cursor 与版本发布流程
java·人工智能·学习·aigc
我爱cope7 小时前
【从0开始学设计模式-10| 装饰模式】
java·开发语言·设计模式
朝新_7 小时前
【Spring AI 】图像与语音模型实战
java·人工智能·spring
RH2312118 小时前
2026.4.16Linux 管道
java·linux·服务器
zmsofts8 小时前
java面试必问13:MyBatis 一级缓存、二级缓存:从原理到脏数据,一篇讲透
java·面试·mybatis
aq55356009 小时前
编程语言三巨头:汇编、C++与PHP大比拼
java·开发语言
我是无敌小恐龙10 小时前
Java SE 零基础入门Day01 超详细笔记(开发前言+环境搭建+基础语法)
java·开发语言·人工智能·opencv·spring·机器学习
心态与习惯11 小时前
Julia 初探,及与 C++,Java,Python 的比较
java·c++·python·julia·比较
一叶飘零_sweeeet11 小时前
优秀文章合集
java
zopple11 小时前
ThinkPHP5.x与3.x核心差异解析
java·python·php