Java字符串进阶:StringBuilder+StringJoiner

🏠个人主页:黎雁

🎬作者简介:C/C++/JAVA后端开发学习者

❄️个人专栏:C语言数据结构(C语言)EasyXJAVA游戏规划程序人生

✨ 从来绝巘须孤往,万里同尘即玉京

文章目录

  • [✨Java字符串进阶:StringBuilder+StringJoiner|高效操作字符串的两大神器 吃透优化原理 ✅](#✨Java字符串进阶:StringBuilder+StringJoiner|高效操作字符串的两大神器 吃透优化原理 ✅)
    • [📌 文章摘要](#📌 文章摘要)
      • [🕒 阅读时长:约20分钟](#🕒 阅读时长:约20分钟)
      • [✅ 适用人群 & 阅读重点](#✅ 适用人群 & 阅读重点)
    • [📖 知识回顾(承上启下,直击痛点)](#📖 知识回顾(承上启下,直击痛点))
    • [一、StringBuilder类核心精讲 🔥 字符串高效操作的核心工具](#一、StringBuilder类核心精讲 🔥 字符串高效操作的核心工具)
      • [1.1 StringBuilder概述(必背核心)](#1.1 StringBuilder概述(必背核心))
      • [1.2 StringBuilder构造方法(两种常用)](#1.2 StringBuilder构造方法(两种常用))
      • [1.3 StringBuilder核心成员方法(开发必备)](#1.3 StringBuilder核心成员方法(开发必备))
      • [1.4 核心方法实战示例(逐一讲解)](#1.4 核心方法实战示例(逐一讲解))
        • [示例1:append() 添加数据(支持链式调用)](#示例1:append() 添加数据(支持链式调用))
        • [示例2:reverse() 反转容器内容](#示例2:reverse() 反转容器内容)
        • [示例3:length() 获取有效字符长度](#示例3:length() 获取有效字符长度)
        • [示例4:toString() 转换为String对象](#示例4:toString() 转换为String对象)
      • [1.5 StringBuilder底层扩容原理(笔试/面试必考)](#1.5 StringBuilder底层扩容原理(笔试/面试必考))
        • [✔ 核心底层设计:字节数组存储](#✔ 核心底层设计:字节数组存储)
        • [✔ 扩容规则(JDK8及以后)](#✔ 扩容规则(JDK8及以后))
        • [✔ 扩容示例解析](#✔ 扩容示例解析)
      • [1.6 StringBuilder经典实战:高效拼接字符串](#1.6 StringBuilder经典实战:高效拼接字符串)
    • [二、StringJoiner类核心精讲 🎨 简洁美化的字符串拼接工具](#二、StringJoiner类核心精讲 🎨 简洁美化的字符串拼接工具)
    • [三、StringBuilder vs StringJoiner 核心对比 📊 按需选择才是关键](#三、StringBuilder vs StringJoiner 核心对比 📊 按需选择才是关键)
    • [四、核心考点提炼 📝 笔试/面试/开发必记](#四、核心考点提炼 📝 笔试/面试/开发必记)
      • [✅ 核心考点1:StringBuilder核心特性](#✅ 核心考点1:StringBuilder核心特性)
      • [✅ 核心考点2:StringBuilder高效的本质](#✅ 核心考点2:StringBuilder高效的本质)
      • [✅ 核心考点3:StringJoiner高频易错点](#✅ 核心考点3:StringJoiner高频易错点)
      • [✅ 核心考点4:三类字符串工具的选择原则](#✅ 核心考点4:三类字符串工具的选择原则)
      • [✅ 经典面试题解析](#✅ 经典面试题解析)
    • [✍️ 写在最后](#✍️ 写在最后)
    • [💡 下期预告](#💡 下期预告)

✨Java字符串进阶:StringBuilder+StringJoiner|高效操作字符串的两大神器 吃透优化原理 ✅

📌 文章摘要

本文是Java字符串系列第二篇核心内容,承接上篇String类的"不可变"特性与痛点,系统讲解StringBuilderStringJoiner两个高频工具类,从类的核心特性、构造方法、成员方法到实战应用,全覆盖高效字符串操作的核心知识点。同时深入剖析StringBuilder底层扩容原理、源码设计,对比两个类的适用场景,解决String类拼接效率低、代码繁琐的问题。全文原理+实战结合,代码注释详尽、考点突出,零基础能快速掌握高效字符串操作方法,在校生可吃透笔试扩容考点,开发入门者能根据业务场景选择合适工具,是攻克Java字符串优化的必备篇章。

🕒 阅读时长:约20分钟

✅ 适用人群 & 阅读重点

▫️ Java零基础入门者 :重点看两个类的构造方法、核心方法示例,跟着敲写代码,掌握字符串高效拼接/拼接美化的基础用法。

▫️ 在校学生/笔试备考者 :吃透StringBuilder底层扩容原理、源码设计 ,这是面试/笔试高频必考考点,同时牢记两类的核心区别。

▫️ 开发入门夯实基础者 :聚焦方法的链式调用、返回值特性,理解为何这两个类能优化String的操作效率,掌握企业开发的编码规范。

▫️ 字符串操作薄弱者 :重点看场景化示例,理清"普通拼接"与"高效拼接"、"简单拼接"与"美化拼接"的使用差异。

▫️ 复习巩固者:直接看「核心考点提炼+类对比总结」,快速梳理核心用法与考点,查漏补缺。

📖 知识回顾(承上启下,直击痛点)

在Java字符串系列第一篇的学习中,我们吃透了String类的核心知识点,也发现了它的核心痛点 :字符串内容不可变,一旦进行拼接、修改等操作,就会在内存中创建大量冗余对象,不仅浪费内存空间,还会降低程序运行效率。

比如多次用+拼接字符串时,有变量参与的情况下会触发运行时多次创建对象,底层即使自动优化也无法彻底解决冗余问题。为了解决这个痛点,Java提供了StringBuilder 类作为字符串操作的优化工具,而在JDK8之后,又推出了StringJoiner 类,在拼接美化场景下让代码更简洁。本篇就来深入学习这两个"字符串高效操作神器",彻底解决String类的操作痛点。

一、StringBuilder类核心精讲 🔥 字符串高效操作的核心工具

1.1 StringBuilder概述(必背核心)

💡 StringBuilder可以看作一个可变的字符串容器,创建之后其内部的内容可以随意修改、添加、删除,不会像String类那样产生大量冗余对象。

  • 核心特性内容可变操作高效,专为字符串的频繁拼接、反转等操作设计;
  • 核心作用 :解决String类拼接效率低、内存浪费的问题,是开发中字符串批量操作的首选工具
  • 包路径java.lang.StringBuilder,无需手动导包。

关键理解:String是不可变的字符串对象 ,而StringBuilder是存储字符串的可变容器,所有操作都在同一个容器中进行,不会创建多余对象。

1.2 StringBuilder构造方法(两种常用)

StringBuilder提供了两个核心构造方法,满足不同初始化需求,直接创建可操作的容器对象:

构造方法 说明 示例
public StringBuilder() 创建一个空的字符串容器,无初始内容 StringBuilder sb = new StringBuilder();
public StringBuilder(String str) 创建一个字符串容器,初始化内容为指定字符串 StringBuilder sb = new StringBuilder("abc");
简单示例:创建StringBuilder对象
java 复制代码
public class StringBuilderCreateDemo {
    public static void main(String[] args) {
        // 空参构造:创建空容器
        StringBuilder sb1 = new StringBuilder();
        System.out.println("空容器内容:" + sb1); // 输出:空容器内容:(无内容)
        
        // 带参构造:创建带初始内容的容器
        StringBuilder sb2 = new StringBuilder("Java字符串");
        System.out.println("带初始内容的容器:" + sb2); // 输出:带初始内容的容器:Java字符串
    }
}

小技巧:Java对StringBuilder做了特殊处理,直接打印对象不会输出地址值,而是输出容器中的实际内容,无需手动调用方法获取,开发更便捷。

1.3 StringBuilder核心成员方法(开发必备)

StringBuilder提供了一系列专为字符串操作设计的方法,核心方法均支持链式调用,且修改操作直接作用于容器本身,以下是最常用的4个核心方法,必须熟练掌握:

方法 作用 特点
public StringBuilder append(任意类型) 向容器中添加数据(字符串、数字、布尔等任意类型) 返回对象本身,支持链式调用
public StringBuilder reverse() 将容器中的所有内容反转 返回对象本身,支持链式调用
public int length() 获取容器中有效字符的长度 与String类用法一致,返回int类型
public String toString() StringBuilder容器转换为String对象 解决StringBuilder无法直接作为String类型使用的问题

1.4 核心方法实战示例(逐一讲解)

示例1:append() 添加数据(支持链式调用)

append()是StringBuilder最常用的方法,可添加任意数据类型,链式调用能让拼接代码更简洁,无需多次写对象名。

java 复制代码
public class StringBuilderAppendDemo {
    public static void main(String[] args) {
        // 创建空容器
        StringBuilder sb = new StringBuilder();
        // 单个添加
        sb.append("Hello");
        sb.append(" ");
        sb.append("Java");
        System.out.println(sb); // 输出:Hello Java
        
        // 链式调用(推荐,代码更简洁)
        sb.append("\n").append(123).append(" ").append(true).append(" ").append(3.14);
        System.out.println(sb); // 输出:Hello Java
                               //      123 true 3.14
    }
}

核心要点:append()返回对象本身,所以才能实现链式调用,这是StringBuilder的核心设计之一。

示例2:reverse() 反转容器内容

专为字符串反转设计,一行代码实现,比手动用String类反转更高效、更简洁。

java 复制代码
public class StringBuilderReverseDemo {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("得鹿梦鱼");
        // 反转内容
        sb.reverse();
        System.out.println(sb); // 输出:鱼梦鹿得
        
        // 链式调用:添加+反转
        StringBuilder sb2 = new StringBuilder();
        sb2.append("123456").reverse();
        System.out.println(sb2); // 输出:654321
    }
}
示例3:length() 获取有效字符长度

用法与String类的length()方法完全一致,返回容器中实际存储的字符个数,而非容器的底层容量。

java 复制代码
public class StringBuilderLengthDemo {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abc");
        sb.append(123).append(true);
        // 获取有效长度
        int len = sb.length();
        System.out.println("容器内容:" + sb); // 输出:abc123true
        System.out.println("有效字符长度:" + len); // 输出:有效字符长度:9
    }
}
示例4:toString() 转换为String对象

StringBuilder是容器 ,并非String类型,当需要将其作为String类型使用(如传入要求String参数的方法)时,需通过toString()转换,转换后得到一个新的String对象。

java 复制代码
public class StringBuilderToStringDemo {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("Java").append("字符串精讲");
        // 转换为String类型
        String str = sb.toString();
        System.out.println("转换后的String:" + str); // 输出:Java字符串精讲
        System.out.println("字符串长度:" + str.length()); // 输出:字符串长度:7
    }
}

1.5 StringBuilder底层扩容原理(笔试/面试必考)

这是StringBuilder的核心考点,理解扩容原理能让你从"会用"升级为"懂原理",彻底吃透这个类的设计思想。

✔ 核心底层设计:字节数组存储

StringBuilder的底层是一个可变的字节数组(用于存储字符的ASCII值),所有添加的内容最终都会存入这个数组,其扩容逻辑围绕这个数组展开:

  1. 默认初始容量 :创建空参的StringBuilder时,底层会默认创建一个长度为16的字节数组;
  2. 带参构造容量 :创建new StringBuilder("abc")时,底层数组容量为初始字符串长度 + 16(如"abc"长度3,容量为19);
  3. 容量与长度的区别
    • 容量:底层数组的总长度(可存储的最大字符数,开发者无需关心);
    • 长度 :容器中实际存储的字符数(通过length()获取)。
✔ 扩容规则(JDK8及以后)

当通过append()添加内容,实际长度超过底层数组容量 时,会触发自动扩容,扩容规则分三步:

  1. 若新增后长度 ≤ 原容量×2+2 → 扩容为原容量×2+2(默认初始16,第一次扩容为34);
  2. 若新增后长度 > 原容量×2+2 → 直接扩容为实际需要的长度(按需扩容,避免内存浪费);
  3. 扩容时会创建新的字节数组,将原数组的内容复制到新数组,后续操作都在新数组中进行。
✔ 扩容示例解析
java 复制代码
// 空参构造,初始容量16,长度0
StringBuilder sb = new StringBuilder();
// 添加16个字符,长度16,未超容量,不扩容
sb.append("1234567890123456");
// 再添加1个字符,长度17>16,触发扩容→新容量34
sb.append("7");
// 再添加20个字符,长度37>34,触发扩容→新容量37(按需扩容)
sb.append("12345678901234567890");

核心总结:StringBuilder高效的本质是在一个可变数组中完成所有操作,仅在容量不足时触发一次扩容,远少于String类拼接时的对象创建次数。

1.6 StringBuilder经典实战:高效拼接字符串

对比String类和StringBuilder类的拼接效果,直观感受后者的高效性,这也是开发中的经典场景。

java 复制代码
public class StringBuilderPractice {
    public static void main(String[] args) {
        // 场景:拼接1-100的数字,对比效率(此处直观展示代码,效率差异大数据量更明显)
        // 方式1:String类拼接(有变量,多次创建对象)
        String str = "";
        for (int i = 1; i <= 10; i++) {
            str += i;
        }
        System.out.println("String拼接:" + str); // 输出:String拼接:12345678910
        
        // 方式2:StringBuilder拼接(单容器,无冗余对象)
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 10; i++) {
            sb.append(i);
        }
        String result = sb.toString();
        System.out.println("StringBuilder拼接:" + result); // 输出:StringBuilder拼接:12345678910
    }
}

开发规范:只要涉及多次字符串拼接(尤其是循环中),一律使用StringBuilder,这是企业开发的通用规范。

二、StringJoiner类核心精讲 🎨 简洁美化的字符串拼接工具

2.1 StringJoiner概述(JDK8新特性)

💡 StringJoiner与StringBuilder一样,也是一个可变的字符串容器 ,内容创建后可修改,核心优势是:在拼接多个字符串时,能自动添加分隔符、前缀、后缀,让代码更简洁,无需手动拼接分隔符

  • 核心特性:内容可变、拼接美化、代码简洁;
  • 出现版本:JDK 8及以后才支持,使用前需确认JDK版本;
  • 包路径java.util.StringJoiner需要手动导包(高频易错点);
  • 核心作用 :替代StringBuilder做带分隔符的拼接 (如数组转字符串[1,2,3]、拼接多个参数a-b-c),代码更简洁。

2.2 StringJoiner构造方法(两个核心)

StringJoiner的构造方法直接关联分隔符、前缀、后缀,这是它与StringBuilder的核心区别,两个构造方法满足不同美化需求:

构造方法 说明 示例 拼接效果
public StringJoiner(CharSequence delimiter) 创建空容器,指定分隔符(多个内容之间的符号) new StringJoiner("---") a---b---c
public StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 创建空容器,指定分隔符+前缀+后缀 new StringJoiner(", ", "[", "]") [1, 2, 3]

小提示:CharSequence是String的父接口,传入字符串直接即可。

2.3 StringJoiner核心成员方法(实用易记)

StringJoiner的方法与StringBuilder相似,核心方法同样支持链式调用,且贴合拼接美化的业务场景,常用方法有3个:

方法 作用 特点
public StringJoiner add(CharSequence newElement) 向容器中添加字符串内容 返回对象本身,支持链式调用
public int length() 获取容器中有效字符的总长度(包含分隔符、前缀、后缀) 返回int类型
public String toString() 将容器内容转换为String对象 最终拼接结果,开发中必用

2.4 StringJoiner实战示例(场景化讲解)

示例1:仅指定分隔符拼接

适用于简单的带分隔符拼接场景,如拼接多个名称、编号。

java 复制代码
import java.util.StringJoiner; // 必须导包

public class StringJoinerDemo1 {
    public static void main(String[] args) {
        // 创建容器,指定分隔符为顿号
        StringJoiner sj = new StringJoiner("、");
        // 添加内容(链式调用)
        sj.add("Java").add("Python").add("C++").add("Go");
        // 转换为String并打印
        System.out.println(sj.toString()); // 输出:Java、Python、C++、Go
    }
}
示例2:指定分隔符+前缀+后缀拼接

这是StringJoiner的核心使用场景,如数组转格式化字符串、集合元素拼接,无需手动添加前缀后缀和分隔符。

java 复制代码
import java.util.StringJoiner;

public class StringJoinerDemo2 {
    public static void main(String[] args) {
        // 创建容器:分隔符为逗号+空格,前缀为[,后缀为]
        StringJoiner sj = new StringJoiner(", ", "[", "]");
        // 循环添加1-5的数字
        for (int i = 1; i <= 5; i++) {
            sj.add(String.valueOf(i)); // 把int转为String
        }
        // 打印结果
        System.out.println(sj); // 输出:[1, 2, 3, 4, 5]
        // 获取总长度([+1+,+ +2+,+ +3+,+ +4+,+ +5+] → 共15)
        System.out.println("总长度:" + sj.length()); // 输出:总长度:15
    }
}
示例3:对比StringBuilder实现相同效果

通过对比,直观感受StringJoiner的代码简洁性,实现同样的[1,2,3]效果,StringBuilder需要手动拼接分隔符、前缀后缀。

java 复制代码
import java.util.StringJoiner;

public class StringJoinerCompare {
    public static void main(String[] args) {
        // 方式1:StringJoiner实现(简洁,一行构造,自动拼接)
        StringJoiner sj = new StringJoiner(", ", "[", "]");
        sj.add("1").add("2").add("3");
        System.out.println("StringJoiner:" + sj); // 输出:[1, 2, 3]
        
        // 方式2:StringBuilder实现(繁琐,手动拼接所有符号)
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        sb.append("1").append(", ").append("2").append(", ").append("3");
        sb.append("]");
        System.out.println("StringBuilder:" + sb); // 输出:[1, 2, 3]
    }
}

核心结论:带分隔符的格式化拼接用StringJoiner,普通拼接/反转用StringBuilder,各司其职。

三、StringBuilder vs StringJoiner 核心对比 📊 按需选择才是关键

很多初学者会混淆这两个类,其实它们的核心定位不同,一个主打通用高效 ,一个主打美化简洁,以下是核心对比,帮你快速选择:

对比维度 StringBuilder StringJoiner
出现版本 JDK5及以后 JDK8及以后
包路径/导包 java.lang,无需导包 java.util,需要导包
核心定位 通用的字符串高效操作工具 带分隔符的格式化拼接工具
核心优势 支持拼接、反转等所有操作,功能全面 自动添加分隔符/前缀/后缀,代码简洁
底层实现 基于字节数组,支持扩容 底层封装了StringBuilder,本质是其封装类
适用场景 1. 任意字符串拼接(尤其是循环) 2. 字符串反转 3. 无格式要求的批量操作 1. 带分隔符的拼接(如a-b-c) 2. 带前后缀的格式化拼接(如[1,2,3]) 3. 数组/集合元素的格式化输出
方法丰富度 方法多,功能全面 方法少,仅聚焦拼接美化

关键知识点:StringJoiner底层其实是封装了StringBuilder,它的高效性本质来自StringBuilder,只是做了上层的美化封装。

四、核心考点提炼 📝 笔试/面试/开发必记

✅ 核心考点1:StringBuilder核心特性

  • 内容可变,是存储字符串的容器,而非不可变对象;
  • 底层是字节数组,默认初始容量16,容量不足时自动扩容,扩容规则为原容量×2+2按需扩容
  • 所有修改方法(append、reverse)都返回对象本身,支持链式调用;
  • 需通过toString()转换为String类型才能作为String参数使用。

✅ 核心考点2:StringBuilder高效的本质

单个可变容器中完成所有操作,仅在容量不足时触发一次扩容,避免了String类拼接时的多次对象创建,节省内存且提高效率。

✅ 核心考点3:StringJoiner高频易错点

  • JDK8及以后才支持,使用前确认版本;
  • 位于java.util包,必须手动导包(笔试编译报错高频点);
  • length()返回的长度包含分隔符、前缀、后缀,并非仅实际内容长度。

✅ 核心考点4:三类字符串工具的选择原则

  1. 简单字符串使用(无修改/拼接)→ 直接用String类(直接赋值,复用串池);
  2. 字符串拼接/反转/批量修改(无格式要求)→ 用StringBuilder(高效通用);
  3. 带分隔符/前后缀的格式化拼接→ 用StringJoiner(代码简洁);
  4. 循环中拼接字符串→ 绝对不用String类,优先用StringBuilder/StringJoiner。

✅ 经典面试题解析

面试题:StringBuilder的初始容量和扩容规则是什么?

答案

  1. 空参构造的StringBuilder底层默认创建长度16的字节数组,初始容量为16;
  2. 带参构造的容量为初始字符串长度 + 16
  3. 当实际存储长度超过容量时触发扩容:若新增长度≤原容量×2+2,扩容为原容量×2+2;若新增长度>原容量×2+2,直接扩容为实际需要的长度;
  4. 扩容时会创建新数组,复制原数组内容,后续操作在新数组中进行。

✍️ 写在最后

本篇我们吃透了Java字符串操作的两大核心优化工具------StringBuilder和StringJoiner,解决了String类"不可变"带来的效率痛点。从核心用法到底层原理,从场景实战到类的对比,我们理清了三者的定位与选择原则:String是基础,StringBuilder是通用优化工具,StringJoiner是格式化拼接的专用工具,三者各司其职,配合使用才能让字符串操作既高效又简洁。

StringBuilder的底层扩容原理是笔试/面试的高频考点,一定要理解透彻,而非死记硬背;而StringJoiner的核心是记住其导包要求、构造方法适用场景,避免开发中出现编译错误或代码冗余。

作为字符串系列的第二篇,我们完成了"高效操作"的核心学习,下一篇将聚焦字符串底层原理深度剖析,包括String拼接的编译期/运行时优化、三大类的内存对比、经典面试题深度解析,实现从"懂用法"到"通原理"的终极跨越。

Java的字符串知识看似简单,实则暗藏诸多考点,只有把每个细节学透,才能在笔试和开发中少踩坑。愿你继续保持对底层原理的探索,夯实每一个基础知识点!✨

💡 下期预告

Java字符串精讲(三):字符串底层原理深度剖析+经典面试题全解|吃透编译期优化/内存机制/高频坑点,实现知识闭环!

本文为Java字符串系列第二篇,案例均经过实测可运行,代码规范贴合企业开发。如果对你有帮助,欢迎点赞+收藏+关注,后续会持续更新Java字符串核心知识点与实战案例!有问题可在评论区留言,逐一回复解答~

相关推荐
我的offer在哪里2 小时前
技术实战:用 Python 脚本高效采集与分析手机操作日志
开发语言·python·智能手机
糖猫猫cc2 小时前
Kite:Kotlin/Java 通用的全自动 ORM 框架
java·kotlin·springboot·orm
u0104058362 小时前
Java微服务架构:设计模式与实践
java·微服务·架构
AI_56782 小时前
测试用例“标准化”:TestRail实战技巧,从“用例编写”到“测试报告生成”
java·python·测试用例·testrail
Anastasiozzzz2 小时前
LRU缓存是什么?&力扣相关题目
java·缓存·面试
工程师0072 小时前
C#中的AutoUpdater自动更新类
开发语言·c#·自动更新开源库·autoupdate
lsx2024062 小时前
Java 泛型
开发语言
jghhh013 小时前
基于MATLAB的可见光通信系统仿真实现
开发语言·matlab
茶本无香3 小时前
@Scheduled(cron = “0 */5 * * * ?“) 详解
java·定时任务·scheduled