字符串拼接常用方法

字符串拼接常用方法字符串 是 Java 中最常用的一个数据类型了 本文 也是对于 Java 中字符串相关知识的一个补充 主要来介绍一下字符串拼接相关的知识 本文基于 jdk1 8 0 181 字符串拼接是我们在 Java 代码中比较经常要做的事情 就是把多个字符串拼接到一起 我们都知道 String 是 Java 中一个不可变的类 所以他一旦被实例化就无法被修改 不可变类的实例一旦创建 其成员变量的值就不能被修改 这

        字符串,是Java中最常用的一个数据类型了。本文,也是对于Java中字符串相关知识的一个补充,主要来介绍一下字符串拼接相关的知识。本文基于jdk1.8.0_181。字符串拼接是我们在Java代码中比较经常要做的事情,就是把多个字符串拼接到一起。我们都知道,String是Java中一个不可变的类,所以他一旦被实例化就无法被修改。(不可变类的实例一旦创建,其成员变量的值就不能被修改。这样设计有很多好处,比如可以缓存hashcode、使用更加便利以及更加安全等)。

      但是,既然字符串是不可变的,那么字符串拼接又是怎么回事呢?字符串不变性与字符串拼接,其实,所有的所谓字符串拼接,都是重新生成了一个新的字符串。下面一段字符串拼接代码:

String s = “abcd”; 

s = s.concat(“ef”);

其实最后我们得到的s已经是一个新的字符串了。如下图:

字符串拼接常用方法

中保存的是一个重新创建出来的String对象的引用。那么,在Java中,到底如何进行字符串拼接呢?字符串拼接有很多种方式,这里简单介绍几种比较常用的。

一,使用+拼接字符串

在Java中,拼接字符串最简单的方式就是直接使用符号+来拼接。如:

String wechat = “Hollis”;

String introduce = “召唤师峡谷”;

String hollis = wechat + “,” + introduce;

这里要特别说明一点,有人把Java中使用+拼接字符串的功能理解为运算符重载。其实并不是,Java是不支持运算符重载的。这其实只是Java提供的一个语法糖。后面再详细介绍。

概念普及:

运算符重载:在计算机程序设计中,运算符重载(英语:operator overloading)是多态的一种。运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

语法糖:语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。

concat  

除了使用+拼接字符串之外,还可以使用String类中的方法concat方法来拼接字符串。如:

String wechat = “Hollis”;

String introduce = “召唤师峡谷”;

String hollis = wechat.concat(“,”).concat(introduce);

StringBuffer

       关于字符串,Java中除了定义了一个可以用来定义字符串常量的String类以外,还提供了可以用来定义字符串变量的StringBuffer类,它的对象是可以扩充和修改的。使用StringBuffer可以方便的对字符串进行拼接。如:

StringBuffer wechat = new StringBuffer(“Hollis”);

String introduce = “召唤师峡谷”;

StringBuffer hollis = wechat.append(“,”).append(introduce);

StringBuilder  

      除了StringBuffer以外,还有一个类StringBuilder也可以使用,其用法和StringBuffer类似。如:

StringBuilder wechat = new StringBuilder(“Hollis”);

String introduce = “召唤师峡谷”;

StringBuilder hollis = wechat.append(“,”).append(introduce);

StringUtils.join  

       除了JDK中内置的字符串拼接方法,还可以使用一些开源类库中提供的字符串拼接方法名,如apache.commons中提供的StringUtils类,其中的join方法可以拼接字符串。

String wechat = “Hollis”; String introduce = “召唤师峡谷”;

System.out.println(StringUtils.join(wechat, “,”, introduce));

这里简单说一下,StringUtils中提供的join方法,最主要的功能是:将数组或集合以某拼接符拼接到一起形成新的字符串,如:

String []list ={“Hollis”,”每日更新Java相关技术文章”};

String result= StringUtils.join(list,”,”);

System.out.println(result); //结果:Hollis,每日更新Java相关技术文章

并且,Java8中的String类中也提供了一个静态的join方法,用法和StringUtils.join类似。

以上就是比较常用的五种在Java种拼接字符串的方式,那么到底哪种更好用呢?为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接呢?

字符串拼接常用方法

接下来我们就来分析一下以上五种方式的底层原理,再来分析到底哪种更好。

使用+拼接字符串的实现原理:

       前面提到过,使用+拼接字符串,其实只是Java提供的一个语法糖, 那么,我们就来解一解这个语法糖,看看他的内部原理到底是如何实现的。还是这样一段代码。我们把他生成的字节码进行反编译,看看结果。

String wechat = “Hollis”;

String introduce = “每日更新Java相关技术文章”;

String hollis = wechat + “,” + introduce;

反编译后的内容如下,反编译工具为jad。

String wechat = “Hollis”; String introduce = “每日更新Java相关技术文章”;

 String hollis = (new StringBuilder()).append(wechat).append(“,”).append(introduce).toString();

通过查看反编译以后的代码,我们可以发现,原来字符串常量在拼接过程中,是将String转成了StringBuilder后,使用其append方法进行处理的。那么也就是说,Java中的+对字符串的拼接,其实现原理是使用StringBuilder.append。

concat是如何实现的

   我们再来看一下concat方法的源代码,看一下这个方法又是如何实现的。

public String concat(String str) {

       int otherLen = str.length();

       if (otherLen == 0) {

             return this;

            }

      int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen);

      str.getChars(buf, len); return new String(buf, true);

}

 这段代码首先创建了一个字符数组,长度是已有字符串和待拼接字符串的长度之和,再把两个字符串的值复制到新的字符数组中,并使用这个字符数组创建一个新的String对象并返回。通过源码我们也可以看到,经过concat方法,其实是new了一个新的String,这也就呼应到前面我们说的字符串的不变性问题上了。

StringBuffer和StringBuilder

接下来我们看看StringBuffer和StringBuilder的实现原理。

和String类类似,StringBuilder类也封装了一个字符数组,定义如下:

char[] value;

与String不同的是,它并不是final的,所以他是可以修改的。另外,与String不同,字符数组中不一定所有位置都已经被使用,它有一个实例变量,表示数组中已经使用的字符个数,定义如下:

int count;其append源码如下:

public StringBuilder append(String str) { super.append(str); return this; }

该类继承了AbstractStringBuilder类,看下其append方法:

public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; }

append会直接拷贝字符到内部的字符数组中,如果字符数组长度不够,会进行扩展。

StringBuffer和StringBuilder类似,最大的区别就是StringBuffer是线程安全的,看一下StringBuffer的append方法。

public synchronized StringBuffer append(String str) {

    toStringCache = null; super.append(str); return this;

}

该方法使用synchronized进行声明,说明是一个线程安全的方法。而StringBuilder则不是线程安全的。

StringUtils.join是如何实现的:

通过查看StringUtils.join的源代码,我们可以发现,其实他也是通过StringBuilder来实现的。

public static String join(final double[] array, final char separator, final int startIndex, final int endIndex) { if (array == null) { return null; } final int noOfItems = endIndex - startIndex; if (noOfItems <= 0) { return EMPTY; } final StringBuilder buf = new StringBuilder(noOfItems * 16); for (int i = startIndex; i < endIndex; i++) { if (i > startIndex) { buf.append(separator); } buf.append(array[i]); } return buf.toString(); }

效率比较:

从结果可以看出,用时从短到长的对比是:StringBuilder < StringBuffer < concat < + < StringUtils.join

所以,阿里巴巴Java开发手册建议:循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。而不要使用+。

总结

本文介绍了什么是字符串拼接,虽然字符串是不可变的,但是还是可以通过新建字符串的方式来进行字符串的拼接。

常用的字符串拼接方式有五种,分别是使用+、使用concat、使用StringBuilder、使用StringBuffer以及使用StringUtils.join。

由于字符串拼接过程中会创建新的对象,所以如果要在一个循环体中进行字符串拼接,就要考虑内存问题和效率问题。

因此,经过对比,我们发现,直接使用StringBuilder的方式是效率最高的。因为StringBuilder天生就是设计来定义可变字符串和字符串的变化操作的。

但是,还要强调的是:

1、如果不是在循环体中进行字符串拼接的话,直接使用+就好了。

2、如果在并发场景中进行字符串拼接的话,要使用StringBuffer来代替StringBuilder。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/203901.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午9:20
下一篇 2026年3月19日 下午9:20


相关推荐

  • 根据请求的后缀判断他应该返回什么样的content_type

    根据请求的后缀判断他应该返回什么样的content_type

    2021年7月2日
    98
  • hive中数据类型转换_csv文件导入sqlserver数据库中

    hive中数据类型转换_csv文件导入sqlserver数据库中1.类型映射关系mysql和hive中的数据类型存在差异,在mysql集成数据到hive中这样的场景下,我们希望在hive中的数据是贴源的,所以在hive中希望创建和mysql结构一致的表。mysql到hive数据类型映射参考如下:mysql数据类型hive数据类型整型bigintBIGINT整型intBIGINT整型smallintBIGINT整型tinyintBIGINT浮点型decimaldecimal浮点型double

    2026年2月8日
    4
  • JetBrains CLion 2021 激活码【中文破解版】

    (JetBrains CLion 2021 激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月28日
    46
  • TIFF World File(TFW)格式说明

    TIFF World File(TFW)格式说明TIFFWorldFil TFW 格式说明 nbsp TIFFWorldFil TFW 格式说明摘要 TFW 文件包含相关的 TIFF 文件的空间参数 spatialrefer 数据 本文详细描述了 TFW 文件中定义的参数 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 概述 nbsp nbsp nbsp nbsp nbsp nbsp 两个文件构成 TFW 格式 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp ASCII 头文件 nbsp nbsp nbsp nbsp nbsp nbsp 图象文件 nbsp nbsp nbsp nbsp nbsp nbsp 图

    2026年3月18日
    2
  • 如何在小型服务器上更新你的OpenClaw

    如何在小型服务器上更新你的OpenClaw

    2026年3月13日
    8
  • Neo4j详解

    Neo4j详解Neo4j 入门详解项目中某种特殊的场景 使用图形数据库比较有独特的优势 所以经过一个多月的奋战终于把项目上线了 本次使用上了图形数据库是 neo4j 社区版 因为数据量不到一个亿 只是关系比较复杂所以社区版基本上 够用 后续货陆续分享 我对 neo4j 社区版高可用相关方面的总结 探活 监控告警 热备 控制台等 本次将一些 neo4j 的一些入门基础知识 做一次项目后的整理总结 ps 有些知识点

    2026年3月26日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号