之前在阅读《阿里巴巴Java开发手册》时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下:

那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符串拼接的效率如何吧(JDK版本为 jdk1.8.0_201)。

执行结果如下:

为什么这两种方法的时间会差这么多呢?接下来让我们一起进一步研究。

为什么 StringBuilder 比 + 快这么多?

从字节码层面来看下,为什么循环体中字符串拼接 StringBuilder 比 + 快这么多?

使用 javac StringConcatDemo.java 命令编译源文件,使用 javap -c StringConcatDemo 命令查看字节码文件的内容。

其中 addMethod() 方法的字节码如下:

可以看出,第 8 行到第 38 行构成了一个循环体:在第 8 行的时候做条件判断,如果不满足循环条件,则跳转到 41 行。编译器做了一定程度的优化,在 11 行 new 了一个 StringBuilder 对象,然后再 19 行、23 行、28 行进行了三次 append() 方法的调用,不过每次循环都会重新 new 一个 StringBuilder 对象。

再来看 stringBuilderMethod() 方法的字节码:

13 行到 30 行构成了循环体,可以看出,在第4行(循环体外)就构建好了 StringBuilder 对象,然后再循环体内只进行 append() 方法的调用。

由此可以看出,在 for 循环中,使用 + 进行字符串拼接,每次都是 new 了一个 StringBuilder,然后再把 String 转成 StringBuilder,再进行 append,而频繁的新建对象不仅要耗费很多时间,还会造成内存资源的浪费。这就从字节码层面解释了为什么不建议在循环体内使用 + 去进行字符串的拼接。

接下来再来让我们看下使用 + 或者 StringBuilder 拼接字符串的原理吧。

使用 + 拼接字符串

在 Java 开发中,最简单常用的字符串拼接方法就是直接使用 + 来完成:

反编译后的内容如下:(使用的反编译工具为 jad)

通过查看反编译以后的代码,可以发现,在字符串常量在拼接过程中,是将 String 转成了 StringBuilder 后,使用其 append() 方法进行处理的。

那么也就是说,Java中的 + 对字符串的拼接,其实现原理是使用 StringBuilder 的 append() 来实现的,使用 + 拼接字符串,其实只是 Java 提供的一个语法糖。

使用 StringBuilder 拼接字符串

StringBuilder 的 append 方法就是第二个常用的字符串拼接姿势了。

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

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

其 append() 方法源码如下:

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

首先判断拼接的字符串 str 是不是 null,如果是,调用 appendNull() 方法进行处理,appendNull() 方法的源码如下:

如果字符串 str 不为 null,则判断拼接后的字符数组长度是否超过当前数组长度,如果超过,则调用 Arrays.copyOf() 方法进行扩容并复制,ensureCapacityInternal() 方法的源码如下:

最后,将拼接的字符串 str 复制到目标数组 value 中。

总结

本文针对《阿里巴巴Java开发手册》中的循环体中拼接字符串建议出发,从字节码层面,来解释为什么 StringBuilder 比 + 快,还分别介绍了字符串拼接中 + 和 StringBuilder 的原理,因此在循环体拼接字符串时,应该使用 StringBuilder 的 append() 去完成拼接。

android string拼接字符串_为什么阿里巴巴不建议在循环体中使用+进行字符串拼接?...相关推荐

  1. java字符串拼接_为什么阿里巴巴不建议在for循环中使用quot;+quot;进行字符串拼接...

    点击上方"Java专栏",选择"置顶或者星标" 第一时间阅读精彩文章! ☞ 程序员进阶必备资源免费送「21种技术方向!」 点击查看☜ 字符串,是 Java 中最 ...

  2. 编写一个C程序,实现以下功能:编写一个常规的函数和一个递归函数,两个函数均能将输入的一个字符串以按反序形式的字符串作为返回值。在main函数中输入一行字符串,分别调用两个函数,输出反序后的字符串。

    题目要求: 编写一个C程序,实现以下功能:编写一个常规的函数和一个递归函数,两个函数均能将输入的一个字符串以按反序形式的字符串作为返回值.在main函数中输入一行字符串,分别调用两个函数,输出反序后的 ...

  3. java里面string什么意思_「Java基础知识」Java中的字符串是什么

    原标题:「Java基础知识」Java中的字符串是什么 字符串顾名思义就是一些字符组合在一起组成的一串数据,称作字符串,在Java中字符串用双引号包围起来,格式为String string = &quo ...

  4. python创建一个字典、关键字为只包含字母的字符串_探究Python源码,终于弄懂了字符串驻留技术...

    摘要:在本文中,我们将深入研究 Python 的内部实现,并了解 Python 如何使用一种名为字符串驻留(String Interning)的技术,实现解释器的高性能. 每种编程语言为了表现出色,并 ...

  5. java 批量替换字符串_# Java 一步一步实现高逼格的字符串替换工具(二)

    Java 一步一步实现高逼格的字符串替换工具(二) 上一篇实现了一个用于字符串替换的方法,主要是利用 正则 + jdk的字符串替换,本篇则会再之前的基础上走一个扩展 1. 之前的方法存在的问题 先把上 ...

  6. python替换excel字符串_【Python代替Excel】9:列表、字符串、字典、推导式

    Python处理数据,最常用的是dataframe结构.但dataframe其实也是由其他对象组成的,比如int.float.字符串等等.今天来了解一下其他常见的对象,熟悉他们的用法. 列表List ...

  7. mysql like带字符串_(转)MySQL数据表中带LIKE的字符匹配查询

    MySQL数据表中带LIKE的字符匹配查询 LIKE关键字可以匹配字符串是否相等. 如果字段的值与指定的字符串相匹配,则符合查询条件,该记录将被查询出来. 如果与指定的字符串不匹配,则不符合查询条件. ...

  8. java 按符号分割字符串_如何根据java根据指定的字符,分割字符串?

    展开全部 根据java根据指定的字符,分割字符串的方法是:e69da5e887aa62616964757a686964616f31333365633866String temp[]=result.sp ...

  9. c++ scanf输入字符串_在C语言中,你真的搞清楚字符串了吗?

    1.C语言中没有字符串这种数据类型,可以通过char的数组来替代: 2.字符串一定是一个char的数组,但char的数组未必是字符串: 3.数字0(和字符'\0'等价)结尾的char数组就是一个字符串 ...

最新文章

  1. python if语句多个条件-关于函数:如何在python中为一个if语句提供多个条件
  2. golang web开发框架 Beego
  3. matplotlib嵌入到pyqt中
  4. c语言中猴子拿香蕉的代码题,猴子分香蕉(2018年第九届蓝桥杯省赛第二题)
  5. 搜狗拼音输入法5.0_搜狗输入法与金山WPS联合放大招,推出quot;金山搜狗拼音输入法quot;...
  6. slf4j + log4j2配置日志引擎
  7. 滴滴滴,ITester软件测试小栈所有资源放送!
  8. windows系统文件和dll文件
  9. 转 XMLHttpRequest().readyState的五种状态详解
  10. 项目管理----项目进度管理
  11. RecyclerView多条目加载
  12. android权限的最佳运用
  13. 字体的分类图示——对网页设计很有益的图
  14. 【无标题】Ds1302驱动代码编写并在Lcd1602液晶显示
  15. author-头文字注释
  16. GDUT - 专题学习3 G - 食物链
  17. MySQL中的事务相关属性以及JDBC编程
  18. 火狐浏览器图形验证码刷新不生效的问题(图片src重新赋值不生效的问题)
  19. 中外合作办学计算机科学与技术有哪些大学,校友会2017中外合作办学大学计算机科学与技术专业排行榜...
  20. 禁用wifi共享精灵、禁用wifi热点、win7禁用wifi

热门文章

  1. HTTP-FLV的两种方式
  2. hosts文件 请检查文件是否在别的程序中打开
  3. leetcode 575. 分糖果(Java版)
  4. leetcode 303. 区域和检索 - 数组不可变(Java版)
  5. Redis实战(三):Redis的List、Set、Hash、sorted_set、skip list
  6. 分布式系统原理 之3 Lease机制
  7. netty系列之:使用netty搭建websocket服务器
  8. python pip国内源_Python 修改pip源为国内源
  9. 内存泄漏(OOM)产生原因
  10. 深入理解函数式编程之柯里化