【Java】Java Stream 中的 collect() 方法详解:流最终操作的核心工具


文章目录

    • 一、介绍
    • [二、`collect()` 是什么?](#二、collect() 是什么?)
    • [三、`collect()` 常见用途总览](#三、collect() 常见用途总览)
    • [四、`collect(Collectors.toList())` ------ 收集为 List](#四、collect(Collectors.toList()) —— 收集为 List)
    • [五、`collect(Collectors.toSet())` ------ 收集为 Set](#五、collect(Collectors.toSet()) —— 收集为 Set)
    • [六、`collect(Collectors.toCollection())` ------ 指定具体集合类型](#六、collect(Collectors.toCollection()) —— 指定具体集合类型)
    • [七、收集为 Map(🔥重点)](#七、收集为 Map(🔥重点))
    • 八、拼接字符串:`joining()`
    • 九、分组:`groupingBy()`
    • 十、分区:`partitioningBy()`
    • [十一、统计(Collectors 提供丰富的统计方法)](#十一、统计(Collectors 提供丰富的统计方法))
    • 十二、把自定义对象字段收集到集合中
    • [十三、自定义 Collector(高级)](#十三、自定义 Collector(高级))
    • 十四、总结

一、介绍

在 Java Stream API 中,collect() 是最重要、使用频率最高的终止操作之一。

它的作用概括起来就是一句话:

把流中的数据按照指定方式收集起来,并转换成我们想要的结果

(集合、字符串、Map、统计结果等)

collect() 的威力来自于它可以搭配 Collectors 工具类使用,实现极为丰富的结果构建方式。


二、collect() 是什么?

方法签名:

java 复制代码
<R, A> R collect(Collector<? super T, A, R> collector);

它接收一个 Collector,用于定义 如何收集流中的元素。

而常用的 Collector 都定义在:

java 复制代码
java.util.stream.Collectors

三、collect() 常见用途总览

用途 示例
收集为 List collect(Collectors.toList())
收集为 Set collect(Collectors.toSet())
转为 Map collect(Collectors.toMap(...))
拼接字符串 collect(Collectors.joining(","))
分组 collect(Collectors.groupingBy(...))
分区 collect(Collectors.partitioningBy(...))
统计 collect(Collectors.counting())
求和 collect(Collectors.summingInt())
求平均值 collect(Collectors.averagingInt())

接下来对常用场景逐一展开。


四、collect(Collectors.toList()) ------ 收集为 List

java 复制代码
import java.util.stream.Collectors;
import java.util.stream.Stream;
List<String> names = Stream.of("Tom", "Jerry", "Alice")
        .collect(Collectors.toList());

System.out.println(names);

输出:

plain 复制代码
[Tom, Jerry, Alice]

五、collect(Collectors.toSet()) ------ 收集为 Set

java 复制代码
Set<Integer> numbers = Stream.of(1, 2, 3, 2)
        .collect(Collectors.toSet());

System.out.println(numbers); // 去重

六、collect(Collectors.toCollection()) ------ 指定具体集合类型

例如要得到一个 LinkedList:

java 复制代码
LinkedList<String> list = Stream.of("A", "B", "C")
        .collect(Collectors.toCollection(LinkedList::new));

七、收集为 Map(🔥重点)

1. key、value 都来自流元素

java 复制代码
Map<String, Integer> map = Stream.of("A", "BB", "CCC")
        .collect(Collectors.toMap(
                str -> str,         // key
                str -> str.length() // value
        ));

2. key 冲突时提供解决方案

java 复制代码
Map<String, Integer> map = Stream.of("A", "A", "B")
        .collect(Collectors.toMap(
                str -> str,
                str -> 1,
                (v1, v2) -> v1 + v2  // key 相同时合并 value
        ));

八、拼接字符串:joining()

1. 无分隔符

java 复制代码
String result = Stream.of("A", "B", "C")
        .collect(Collectors.joining());

System.out.println(result); // ABC

2. 有分隔符

java 复制代码
String result = Stream.of("A", "B", "C")
        .collect(Collectors.joining(","));

3. 有前缀和后缀

java 复制代码
String result = Stream.of("A", "B", "C")
        .collect(Collectors.joining(",", "[", "]"));

System.out.println(result); // [A,B,C]

九、分组:groupingBy()

非常强大的功能 ------ 按字段分组。

java 复制代码
Map<Integer, List<String>> groups = Stream.of("Java", "Go", "C++", "SQL")
        .collect(Collectors.groupingBy(String::length));

System.out.println(groups);

输出:

plain 复制代码
{
 2=[Go], 
 3=[C++, SQL], 
 4=[Java]
}

十、分区:partitioningBy()

按条件分成两组(true / false)。

java 复制代码
Map<Boolean, List<Integer>> result = Stream.of(1,2,3,4,5)
        .collect(Collectors.partitioningBy(n -> n % 2 == 0));

System.out.println(result);

输出:

plain 复制代码
{false=[1, 3, 5], true=[2, 4]}

十一、统计(Collectors 提供丰富的统计方法)

  1. 求数量:counting()
java 复制代码
long count = Stream.of(1, 2, 3, 4)
        .collect(Collectors.counting()); //4
  1. 求和:summingInt()
java 复制代码
int sum = Stream.of(1, 2, 3)
        .collect(Collectors.summingInt(n -> n)); // 6
  1. 求平均值:averagingInt()
java 复制代码
double avg = Stream.of(1, 2, 3)
        .collect(Collectors.averagingInt(n -> n)); //2
  1. 一次性汇总所有统计结果:summarizingInt()
java 复制代码
IntSummaryStatistics summary = Stream.of(1, 2, 3, 4)
        .collect(Collectors.summarizingInt(n -> n));

System.out.println(summary);

输出类似:

plain 复制代码
IntSummaryStatistics{count=4, sum=10, min=1, average=2.500000, max=4}

十二、把自定义对象字段收集到集合中

示例:

java 复制代码
class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

List<Person> people = List.of(
    new Person("Tom", 20),
    new Person("Alice", 22)
);

List<String> names = people.stream()
        .map(p -> p.name)
        .collect(Collectors.toList());

System.out.println(names);

十三、自定义 Collector(高级)

collect() 也可以自定义收集逻辑:

java 复制代码
List<String> result = Stream.of("a", "b", "c")
        .collect(
                ArrayList::new,  // 创建容器
                ArrayList::add,  // 添加元素
                ArrayList::addAll // 合并
        );

System.out.println(result);

十四、总结

collect() 的核心作用:

把流中的元素转换成我们需要的各种结构(List / Set / Map / String / 分组 / 统计)。

最常见用法:

方法 作用
toList() 收集为 List
toSet() 收集为 Set
toMap() 收集为 Map
joining() 拼接字符串
groupingBy() 分组
partitioningBy() 分区
counting()、summingInt() 统计
summaryStatistics() 汇总统计

参考资料

讲透JAVA Stream的collect用法与原理,远比你想象的更强大 - 是Vzn呀 - 博客园

B站黑马程序员教程

相关推荐
古法老登瞎折腾3 小时前
大数据智能运维实战(十一):运维 MCP 的工程化——权限、限流、审计与错误处理
java·大数据·运维·spring ai·mcp
学逆向的3 小时前
C 堆区内存管理
c语言·开发语言·网络安全
huoyueyi3 小时前
《融天AI-APP从0到1开发实录》
开发语言·lua
智能运维指南4 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
yz_aiks4 小时前
Spring AI 2.1 ChatMemory 已过时用什么替代:迁移到 Session Memory 实战(JDBC 存储与会话压缩)
java·spring boot·大模型·ai agent·spring ai
金銀銅鐵5 小时前
[Java] 用 GUI 展示 EnumMap 增删键值对时的内部变化
java·后端·ai编程
学长毕设5 小时前
基于SpringBoot的上门洗车服务系统设计与实现
java·spring boot·后端
jason成都5 小时前
RTKLIB-Java 多基线联合RTK:FIX率从0%到91.5%的三层根因修复
java·gnss·rtklib·rtklib_java
OpenAnolis小助手5 小时前
PHP 两个严重漏洞曝光,龙蜥社区 24 小时完成 3 版本修复
开发语言·操作系统·php·龙蜥社区
鱼宵5 小时前
Stream 终端操作一次讲透:collect、count、reduce 怎么选
java·stream·终端操作