文档章节

关于Java字符串的拼接,你了解多少?

小祝特烦恼
 小祝特烦恼
发布于 2017/04/21 11:38
字数 746
阅读 93
收藏 0

关于Java字符串的拼接,你了解多少?

前景

昨晚开了一个review会,就在循环内部创建String对象的问题展开了激烈的讨论。今早小伙伴们意犹未尽,就字符串的拼接又一次在群里炸开了锅。作为一个有几年工作经验的我来说,在这次的讨论中受益匪浅。

代码中常见的字符串拼接方式

用“+”拼接字符串

String ab = "a" + "b";

输出 : ab

String.format()

String ab = String.format("%s%s","a","b");

输出 : ab

StringBuilder和StringBuffer

StringBuilder sb = new StringBuilder()
sb.append(“a”);
sb.append(“b”);
String ab = sb.toString();

输出 : ab

性能测试

网上对它们的性能普遍认为“+号”性能较差。为了看出效果,时间单位为微秒,纳秒有点太小了。

String a1 = "a";
String b1 = "b";
Thread.sleep(1000);
long start1 = System.nanoTime();
String ab1 = a1 + b1;
long end1 = System.nanoTime();
System.out.println("+号拼接 : " + ((end1 - start1) / 1000) + "ws");     


String a2 = "a";
String b2 = "b";
Thread.sleep(1000);
long start2 = System.nanoTime();
String ab2 = String.format("%s%s", a2, b2);
long end2 = System.nanoTime();
System.out.println("String.format() : " + ((end2 - start2) / 1000)+ "ws");      


String a3 = "a";
String b3 = "b";
Thread.sleep(1000);
long start3 = System.nanoTime();
StringBuilder sb = new StringBuilder();
sb.append(a3);
sb.append(b3);
String ab3 = sb.toString();
long end3 = System.nanoTime();
System.out.println("StringBuilder.append() : "+ ((end3 - start3) / 1000)+ "ws");


输出 : 
+号拼接 : 127ws
String.format() : 46584ws
StringBuilder.append() : 62ws


你可以再试试5以内的字符串拼接。结果差不多。

结果

在2-5个数左右的字符串拼接中“+”号拼接和StringBuilder的耗时相差无几,而String.format()耗时较多

分析

为了进一步了解String,查看到了JDK1.6的源码,String.class开头注释写到

  • The Java language provides special support for the string
  • concatenation operator ( + ), and for conversion of
  • other objects to strings. String concatenation is implemented
  • through the <code>StringBuilder</code>(or <code>StringBuffer</code>)
  • class and its <code>append</code> method.
  • String conversions are implemented through the method
  • <code>toString</code>, defined by <code>Object</code> and
  • inherited by all classes in Java. For additional information on
  • string concatenation and conversion, see Gosling, Joy, and Steele,
  • <i>The Java Language Specification</i>.

这段话的大致意思就是说

java语言提供了字符串串联运算符,和其他对象转换为字符串,字符串连接是底层通过StringBuilder或者StringBuffer来实现的。

这下就明白了为什么“+”号拼接和StringBuilder拼接的耗时相差无几了,但为什么String.format()的耗时相差甚远呢?

public static String format(String format, Object ... args) {
	return new Formatter().format(format, args).toString();
}

public Formatter() {
	init(new StringBuilder(), Locale.getDefault());
}

在上述代码中不难看出底层也是用StringBuilder实现的,这就不能理解了,同样是StringBuilder,为什么相差那么大呢?咱们接着往下看。

 private FormatString[] parse(String s) {
	ArrayList al = new ArrayList();
	Matcher m = fsPattern.matcher(s);
        ...
}

上述代码是在new Formatter().format()方法中找到的,原来内部有正则匹配操作。众所周知,正则匹配是很消费性能的。这下可以解开心中的迷惑了。

结论

  • 就可读性和简洁性而言,数量不多的拼接,“+”号拼接是个很不错的字符串拼接方式。
  • String.format()还没找到适合用他的场景。(也许是需要正则匹配,有的话请告诉我)
  • 循环中StringBuilder和StringBuffer性能更优。

© 著作权归作者所有

小祝特烦恼

小祝特烦恼

粉丝 40
博文 11
码字总数 9503
作品 0
南京
高级程序员
私信 提问
05《Java核心技术》之三种字符串类有什么区别?

一、提出问题 今天,我们来聊聊日常使用的字符串,别看它似乎很简单,但其实字符串几乎在所有编程语言里都是个特殊的存在,因为不管是数量还是体积,字符串都是大多数应用中的重要组成。 今天...

飞鱼说编程
2018/09/24
0
0
java-----string stringbuffer stringwriter

string 是Java参数传递(by value)造成的,是不可变的(immutable).,例如 基本类型,String传值,复制了值传递过去;可变的(Object)传值,复制了引用传递过去。 String a = "a";//假设a指向地...

风林火山
2011/01/10
0
0
JVM字节码与Java代码层调优

jvm字节码指令 我们都知道,Java源代码不会像C/C++那样直接被编译为机器码,而是被编译成字节码,这造就了Java可以跨平台的特性。JVM实际执行的也是编译后的字节码,所以想要在Java代码层进行...

ZeroOne01
2018/07/27
0
0
我终于搞清楚了和String有关的那点事儿。

String,是Java中除了基本数据类型以外,最为重要的一个类型了。很多人会认为他比较简单。但是和String有关的面试题有很多,下面我随便找两道面试题,看看你能不能都答对: Q1:定义了几个对...

2018/06/24
0
0
升级到JDK9的一个BUG,你了解吗

概述 前几天在一个群里看到一个朋友发了一个demo,说是JDK的bug,昨天在JVM的一个群里又有朋友发了,觉得挺有意思,分享给大家,希望大家升级JDK的版本的时候注意下是否存在这样的代码,如果...

你假笨
2018/06/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

分享一波 RabbitMQ 面试题有答案

1、什么是rabbitmq 2、为什么要使用rabbitmq 3、使用rabbitmq的场景 4、如何确保消息正确地发送至RabbitMQ? 如何确保消息接收方消费了消息? 发送方确认模式 接收方确认机制 接收方消息确认...

搜云库技术团队
3分钟前
0
0
2019年JAVA面试题(高级资深)

记录下本年度最新的面试题: 2019-04-24 //某互联网公司,劳工资源管理方向职位 1.bio/nio/aio介绍下,粘包、拆包问题怎么解决? 2.数据库四个特性是什么,事务传播性是怎么样的?spring事务和...

em_aaron
6分钟前
0
0
yarn如何全局安装命令以及和环境变量的关系

npm全局安装 npm i -g xxx yarn 全局安装 yarn global add xxx 然而你可能会发现npm全局安装后的命令可以直接使用,而yarn却不行,这是为什么呢? 我们来查看下npm和yarn的bin目录 使用npm全...

单线程生物
15分钟前
0
0
异步线程RequestContextHolder.getRequestAttributes()为null

使用Spring框架,在Service中开启一个新的线程,在新的线程中使用 RequestAttributes ra = RequestContextHolder.getRequestAttributes(); 获取出来为null,有没有什么办法能解决? 问题出现...

xiaomin0322
18分钟前
0
0
mingw64环境搭建

mingw64环境搭建 转自:http://www.cr173.com/soft/132367.html MinGW64位版,默认编译出来是64位的,需要编译32位请使用-m32 参数!mingw是一款gnu工具集合是Minimalist GNU on Windows的简称...

shzwork
20分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部