327. Java Stream API - 实现 joining() 收集器:从简单到进阶

文章目录

  • [327. Java Stream API - 实现 `joining()` 收集器:从简单到进阶](#327. Java Stream API - 实现 joining() 收集器:从简单到进阶)
    • [🧱 基础版 `Joining` 收集器实现](#🧱 基础版 Joining 收集器实现)
    • [📦 示例使用](#📦 示例使用)
      • [✅ 输出结果:](#✅ 输出结果:)
    • [🎯 关键点讲解](#🎯 关键点讲解)
    • [💡 思考:为什么没有使用 `IDENTITY_FINISH`?](#💡 思考:为什么没有使用 IDENTITY_FINISH?)
    • [🌟 进阶版:带分隔符、前缀和后缀](#🌟 进阶版:带分隔符、前缀和后缀)
    • [🚀 带参数的 Joining 实现示例](#🚀 带参数的 Joining 实现示例)
    • [✅ 使用方式](#✅ 使用方式)
    • [🧠 总结](#🧠 总结)

327. Java Stream API - 实现 joining() 收集器:从简单到进阶

在 Java Stream API 中,Collectors.joining() 是一个专门用于字符串拼接的收集器。它将多个字符串元素连接成一个单一字符串。今天我们将手动实现这个收集器,并理解其背后的实现机制。


🧱 基础版 Joining 收集器实现

我们首先实现一个最基础的 joining() 收集器版本,不带任何分隔符、前缀或后缀。

java 复制代码
class Joining implements Collector<String, StringBuffer, String> {

    @Override
    public Supplier<StringBuffer> supplier() {
        return StringBuffer::new; // 用于累加字符串的可变容器
    }

    @Override
    public BiConsumer<StringBuffer, String> accumulator() {
        return StringBuffer::append; // 将每个字符串追加到容器中
    }

    @Override
    public BinaryOperator<StringBuffer> combiner() {
        return StringBuffer::append; // 合并两个 StringBuffer(用于并行流)
    }

    @Override
    public Function<StringBuffer, String> finisher() {
        return Object::toString; // 将 StringBuffer 转换成最终的字符串
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Set.of(); // 没有特性:不是 UNORDERED,也不是 IDENTITY_FINISH,也不支持并发
    }
}

📦 示例使用

java 复制代码
Collection<String> strings = List.of("one", "two", "three", "four", "five");

String result = strings.stream()
    .collect(new Joining());

System.out.println("result = " + result);

✅ 输出结果:

java 复制代码
result = onetwothreefourfive

🎯 关键点讲解

方法 作用
supplier() 提供一个 StringBuffer 实例,作为中间结果的容器
accumulator() 将流中的每个字符串添加到容器中
combiner() 合并两个部分结果(并行流场景)
finisher() 把 StringBuffer 转换为最终结果 String
characteristics() 返回空集合,表示没有特性

💡 思考:为什么没有使用 IDENTITY_FINISH?

因为 StringBuffer 和最终返回的类型 String 是不同的类型,所以不能声明为 IDENTITY_FINISH。一旦 finisher() 不是"返回原值",就必须省略该特性。


🌟 进阶版:带分隔符、前缀和后缀

你可能想实现这样的拼接:

java 复制代码
String result = strings.stream()
    .collect(Collectors.joining(", ", "[", "]"));
// 输出: [one, two, three, four, five]

这时候我们就需要使用 StringJoiner 作为中间容器了,因为它原生支持 delimiter(分隔符) 、prefix(前缀) 和 suffix(后缀)。


🚀 带参数的 Joining 实现示例

java 复制代码
class JoiningWithDelimiter implements Collector<String, StringJoiner, String> {
    private final String delimiter;
    private final String prefix;
    private final String suffix;

    public JoiningWithDelimiter(String delimiter, String prefix, String suffix) {
        this.delimiter = delimiter;
        this.prefix = prefix;
        this.suffix = suffix;
    }

    @Override
    public Supplier<StringJoiner> supplier() {
        return () -> new StringJoiner(delimiter, prefix, suffix);
    }

    @Override
    public BiConsumer<StringJoiner, String> accumulator() {
        return StringJoiner::add;
    }

    @Override
    public BinaryOperator<StringJoiner> combiner() {
        return StringJoiner::merge;
    }

    @Override
    public Function<StringJoiner, String> finisher() {
        return StringJoiner::toString;
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Set.of(); // 同样不能是 IDENTITY_FINISH
    }
}

✅ 使用方式

java 复制代码
String result = strings.stream()
    .collect(new JoiningWithDelimiter(", ", "[", "]"));

System.out.println("result = " + result);

输出结果:

java 复制代码
result = [one, two, three, four, five]

🧠 总结

特性 基础版 进阶版
容器类型 StringBuffer StringJoiner
是否支持分隔符/前缀/后缀 否 ✅ 支持
finisher 是 identity 吗? 否 否
特性集(characteristics) 空 空
相关推荐
AC赳赳老秦6 分钟前
OpenClaw 与 FineBI 联动方案:公开数据自动采集与实时业务分析看板实践
大数据·开发语言·python·php·finebi·deepseek·openclaw
通信瓦工10 分钟前
OCP 冷却环境与冷却剂分配单元(CDU)子项目
java·开发语言
坤坤子吖31 分钟前
Python基础语法学习:函数
开发语言·笔记·python·学习
言乐635 分钟前
Python体现逻辑回归和决策树的区别
开发语言·python·算法·决策树·逻辑回归
LOVE️YOU41 分钟前
Python 类与对象的核心逻辑:从 self、cls 到点号、括号与链式调用
开发语言·python
顶点多余1 小时前
C/C++常见面试题
开发语言·c++
(Charon)1 小时前
【C++面试】右值引用与移动语义:std::move到底做了什么
开发语言·c++
TheITSea1 小时前
JavaScript Web APIs
开发语言·前端·javascript
空心木偶☜1 小时前
A2A2A(多智能体协作)
开发语言·python·ai·ai编程
Cc.Y1 小时前
Java零基础入门:类与对象深度掌握 —— 从“零散变量“到“打包管理“
java·开发语言·python