当前位置:首页 > 文章列表 > 文章 > java教程 > Java StringJoiner merge 为什么不保留对方前后缀

Java StringJoiner merge 为什么不保留对方前后缀

来源:17golang原创 2026-11-08 01:51:04 0浏览 收藏

StringJoiner.merge 不会把来源对象的 prefix 和 suffix 再套到目标对象上。它读取来源 joiner 的内部元素内容,把这段内容作为目标 joiner 的一个新元素追加;如果来源使用了不同的分隔符,来源内部元素会先按自己的分隔符拼成一个整体。

官方文档:https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/StringJoiner.html

merge(other) 合并的是来源对象去掉前后缀后的内容,而不是完整的 other.toString()。因此目标 joiner 的前后缀仍由目标对象负责,来源的格式外壳不会重复出现。
  • 目标对象保留自己的 prefix、suffix 和 delimiter。
  • 来源对象只贡献内部元素;来源的 prefix、suffix 不参与合并。
  • 来源分隔符与目标不同时,来源内部文本会作为目标的一个整体元素追加。
  • 来源为空时,merge 对目标没有效果;本文只讨论非空来源的格式边界。

merge 实际追加了什么内容

可以把 StringJoiner 看成“内部元素集合 + 自己的渲染格式”。调用 toString() 时,当前对象才会把自己的前缀、分隔符和后缀拼到内部元素周围。merge 不会把来源的完整字符串结果拿来再次包裹,而是取来源的内部内容作为一个元素放进目标对象。

例如,目标 joiner 的格式是方括号,来源 joiner 的格式是圆括号。来源最终显示为 (C;D),但合并时目标得到的不是完整格式复制;来源的圆括号属于来源的展示边界,不会成为目标的外层边界。

Java StringJoiner merge 中目标前后缀与来源内部内容边界的静态结构说明图
图1:说明图把目标 StringJoiner 的格式边界与来源 joiner 的内部内容分开表示;这是静态结构图,不是运行截图。

用最小代码重现前后缀边界

下面的示例让目标和来源使用不同的前后缀,然后调用一次 merge。目标外层符号来自目标对象,来源内部的 C;D 被作为一个整体元素放入目标。

import java.util.StringJoiner;

public class StringJoinerMergeDemo {
    public static void main(String[] args) {
        StringJoiner target = new StringJoiner("|", "[", "]");
        target.add("A").add("B");

        StringJoiner source = new StringJoiner(";", "(", ")");
        source.add("C").add("D");

        // merge 只吸收 source 的内部内容,不复制 source 的前缀和后缀。
        target.merge(source);

        // 目标对象负责最终的方括号,来源对象负责内部的分号分隔。
        System.out.println(target);
    }
}

这里的关键不是把两个字符串直接相加,而是两个 joiner 的职责不同:source 先把自己的元素组织成内部片段,target 再把这个片段当成一个元素参与自己的渲染。

[A|B|C;D]

这也解释了“为什么不保留对方前后缀”:前后缀不是来源元素本身,而是来源对象输出时使用的展示边界;merge 的契约明确排除了这两个边界。

分隔符不同,为什么来源会变成一个整体元素

如果目标使用 |,来源使用 ;,两者不能简单地把来源的每个元素拆开后改用目标分隔符。官方契约选择把来源的内部元素按来源分隔符连接成一段,再把这段作为目标的单个元素追加。这样来源内部的组织方式不会被目标分隔符重新解释。

因此,下面两种想法的结果不同:

  • target.merge(source):把来源内部的 C;D 作为一个元素追加,目标结果类似 [A|B|C;D]。
  • 逐个调用 target.add:把 C、D 分别交给目标,目标分隔符会参与每个元素之间的连接,结果会类似 [A|B|C|D]。

如果业务要求保留来源的整体格式,merge 适合表达层级组合;如果业务要求把来源元素拆平到目标分隔符下,就应明确遍历来源数据并逐个 add,不要把 merge 当成扁平化操作。

Java StringJoiner 不同分隔符下来源内部内容作为单个元素合并的静态结构说明图
图2:说明图展示目标分隔符、来源分隔符和合并后单元素之间的边界;这是解释图,不是性能或运行结果。

排查 merge 结果不符合预期时,先看这三个判断

第一,看调用方向。target.merge(source) 修改的是目标对象,目标的前后缀决定最终外层显示;把调用方向写反,结果的外层格式也会跟着改变。

第二,看你要的是“组合”还是“摊平”。merge 把来源内部内容作为一个元素加入目标,适合保留来源内部的分隔关系;若想让每个来源元素都使用目标分隔符,需要从原始元素集合重新添加。

第三,不要拿 source.toString() 的完整结果去推断 merge 的输入。来源的 prefix 和 suffix 只在来源自己转换成字符串时参与输出,不能据此认为它们会作为普通元素进入目标。

import java.util.StringJoiner;

public class StringJoinerFlattenDemo {
    public static void main(String[] args) {
        StringJoiner target = new StringJoiner("|", "[", "]");
        // 需要扁平化时,显式把每个业务元素交给目标 joiner。
        target.add("A").add("B");
        target.add("C").add("D");

        // 逐个 add 会让目标分隔符作用于 C 和 D。
        System.out.println(target);
    }
}

这个例子没有调用 merge,因为目标是扁平化而不是组合。选择 API 前先写清楚“来源是一整个元素,还是一组要重新分隔的元素”,通常就能避免前后缀和分隔符的误解。

一张表记住 StringJoiner.merge 的归属

对象/属性merge 后的作用排查结论
目标 prefix保留并包住最终结果最终外层前缀看目标对象
目标 suffix保留并包住最终结果最终外层后缀看目标对象
来源 prefix/suffix不作为元素进入目标不会因为 merge 重复包裹
来源内部元素按来源分隔符组成一个整体元素不同分隔符时不会被目标重新拆分
空来源对目标没有效果先确认来源是否真正添加过元素

常见问题

merge 是不是等价于 target.add(source.toString())?

不是。这样写会把来源的前缀和后缀也当成普通文本加入目标;merge 的契约明确使用来源去掉前后缀后的内部内容。

怎样让来源的每个元素都使用目标分隔符?

不要依赖 merge 做拆平。保留原始元素集合,遍历后逐个调用目标的 add;这样目标分隔符才会作用于每一项。

为什么来源的圆括号没有出现在结果里?

因为圆括号是来源 joiner 的展示边界,不是来源内部元素。merge 只把来源内容作为一个元素追加,最终外层格式由目标对象决定。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Java Pattern 怎样避免灾难性回溯Java Pattern 怎样避免灾难性回溯
上一篇
Java Pattern 怎样避免灾难性回溯
Java 26 API 文档怎样按模块查找类
下一篇
Java 26 API 文档怎样按模块查找类
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    934次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    938次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1047次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1020次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    847次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码