一、分析 

对于一个字符串进行拼接有三种方法:加号、concat方法、及StringBuiler或StringBuffer。

1."+"方法拼接字符串 

str += "c";等效于:str = new StringBuffer(str).append("c").toString();

虽然编译器对字符串加号做了优化,它会用StringBuffer的append方法进行追加。再是通过toString方法转换成String字符串的。

它与纯粹的append方法是不同的:

一是每次都要创建一个StringBuilder对象;

二是每次执行完毕都要调用toString方法将其转换为字符串。

2.concat方法拼接 

concat方法的源码:

public string concat(String str){
int otherLen = str.length(); //如果追加的字符串长度为0,则返回字符串本身
if(otherLen == 0){
return this;
} //字符串数组,容纳的是新字符串的字符
char buf[] = new char[count + otherLen];
//取出原字符串放到buf数组中
getChars(0, count, buf, 0);
//追加的字符串转化成字符串数组,添加到buf中
str.getChars(0, otherLen, buf, count);
//赋值字符数组,产生一个新的字符串
return new String(0, count + otherLen, buf);
}

从整体上看就是一个数组的拷贝,虽然在内存中的处理都是原子性操作,速度非常快,注意看最后的return语句,每次的concat操作都会创建一个新的String对象,这就是concat速度慢下来的原因。

3.appned方法拼接

StringBuilder的appned方法字节由父类的AbstractStringBuilder实现,代码如下:

public AbstractStringBuilder append(String str){
//如果是null值,则把null作为字符串处理
if(str == null)str = "null"; int len = str.length();
//字符串的长度为0,则返回自身
if(len == 0)return this; int newCount = count + len;
//追加后的字符串组长度是否超过当前值
if(newCount > value.length)
expandCapacity(newCount);//加长,并作数组拷贝
//字符串复制到目标数组
str.getChars(0, len, value, count);
count = newCount; return this;
}

整个append方法都在做字符数组处理,加长,然后数组拷贝,这些都是基本的数据处理,没有新建任何对象,所以速度也就最快了!

二、场景 

看看如下代码:

public static void doWithStringBuffer(){
StringBuilder db = new StringBuilder("a");
for(int I = 0; I < 50000; I ++){
sb.append("c");
//str += "c";
//str = str.concat("c");
}
String str = sb.toString();
}

1.StringBuffer的append方法执行时间是0毫秒,时间非常短暂;

2.contact方法次之,由上分析,每次的concat操作都需要创建一个String对象,它创建了5万个String对象;

3.加法拼接,每次创建一个StringBuilder对象,并执行完毕调用toString()方法转换。它创建了5万个StringBuilder对象,toString转换5万次。

三、建议 

三者的实现方法不同,性能也就不同,但是并不表示一定要使用StringBuilder,这是因为“+”非常符合我们的编程习惯,适合人类阅读,大多数情况下,我们使用加号操作。

只有在系统系能临界(如在性能“增长一分则太长”的情况下)的时候,才考虑使用concat或append方法。而且很多时候系统80%的性能是消耗在20%的代码上的,我们的精力应该更多的投入到算法和结构上。

提高你的Java代码质量吧:让我们疑惑的字符串拼接方式的选择的更多相关文章

  1. 提高你的Java代码质量吧:推荐在复杂字符串操作中使用正则表达式

    一.分析  字符串的操作,诸如追加.合并.替换.倒序.分隔等,都是在编码过程中经常用到的,而且Java也提供了append.replace.reverse.split等方法来完成这些操作,它们使用起来 ...

  2. 提高你的Java代码质量吧:少用静态导入

    一.分析  从Java 5开始引入静态导入语法(import static),其目的是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序. 但是,滥用静态导入会使程序更难阅读,更难维护.静态导 ...

  3. 提高你的Java代码质量吧:如果有必要,使用变长数组吧

    一.分析  Java中的数组是定长的,一旦经过初始化声明就不可改变长度,这在实际使用中非常不方便. 二.场景  比如要对班级学生的信息进行统计,因为我们不知道一个班级会有多少学生(随时都有可能会有学生 ...

  4. 提高你的Java代码质量吧:小心switch带来的空值异常

    一.分析  使用枚举定义常量时,会有伴有大量的switch语句判断,目的是为每个枚举解释其行为. 我们知道,目前的Java的switch语句只能判断byte.short.char.int类型(JDK7 ...

  5. 提高你的Java代码质量吧:使用valueof前必须进行校验

    一.分析 每个枚举都是java.lang.Enum的子类,都可以访问Enum类提供的方法,比如hashCode.name.valueOf等,其中valueOf方法会把一个String类型的名称转变成枚 ...

  6. 提高你的Java代码质量吧:不要让类型默默转换

    一.分析  在Java运算中的类型转换,是先运算在进行类型转换的.具体场景如下. 二.场景  在如下程序中: public class Client{ public static final int ...

  7. 提高你的Java代码质量吧:谨慎包装类型的比较

    一.分析  基本类型可以比较大小,其所对应的包装类型都实现了Comparable接口此问题. 二.场景  代码如下: public class Client{ public static void m ...

  8. 提高你的Java代码质量吧:使用构造函数协助描述枚举项

    一.分析 一般来说,我们经常使用的枚举项只有一个属性,即排序号,其默认值是从0.1.2... ....但是除了排序号外,枚举还有一个(或多个)属性. 二.场景 比如,可以通过枚举构造函数声明业务值,定 ...

  9. 提高你的Java代码质量吧:正确使用String、StringBuffer、StringBuilder

    一.建议  CharSequence接口有三个实现类与字符串相关:String.StringBuffer.StringBuilder,虽然它们都与字符串相关,但是其处理机制不同. 根据不同的场景,建议 ...

随机推荐

  1. 一些iOS笔试题目

    1.什么是arc?(arc是为了解决什么问题诞生的?) 首先解释ARC: automatic reference counting自动引用计数. ARC几个要点: 在对象被创建时 retain cou ...

  2. 最全java的读写操作(转载)

    Java的I/O系统中的输入输出流为我们进行开发提供了很多便利,利用其强大的封装性,通过各种组合能够实现多种多样的功能.但是Java提供了很多输入输出流类,在概念和使用上有很多相似之处,所以给很多开发 ...

  3. js bind

    1.作用 函数的bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数. //bind 相比于call apply   this 都等于 obj;   bind是产生一个新的函数 不执 ...

  4. Java数据库连接池的几种配置方法(以MySQL数据库为例)

    Java数据库连接池的几种配置方法(以MySQL数据库为例) 一.Tomcat配置数据源: 前提:需要将连接MySQL数据库驱动jar包放进Tomcat安装目录中common文件夹下的lib目录中 1 ...

  5. C++ Primer 5th 第16章 模板与泛型编程

    模板是C++中泛型编程的基础,一个模板就是创建一个类或者函数的蓝图或者说公式. C++模板分为函数模板和类模板. 类模板则可以是整个类是个模板,类的某个成员函数是个模板,以及类本身和成员函数分别是不同 ...

  6. 初涉JavaScript模式 (12) : 沙箱模式

    引子 上一篇说了模块模式,而对于其中的命名空间模式其实也是有着一些问题,比如每添加一个模块或则深入叠加都会导致长命名,并且对于多个库的不同版本同时运行,一不小心就会污染全局标识,而这两天也发现了JSe ...

  7. Linux_hadoop_install

    1. Build Linux env my env is VM RedHat Linux 6.5 64bit    set fixed IP                  vim /etc/sys ...

  8. SpEL快速入门

    Spring表达式语言(简称SpEL)是一种鱼JSP2 EL功能类似的变道时语言,它可以在运行时查询和操作对象图.与JSP 2的EL相比,SpEL功能更加强大,它甚至支持方法的调用和基本字符串模板. ...

  9. Ant快速入门(一)-----Ant介绍

    Ant是一种基于Java的生成工具.从作用上来看,它类似于C编程(UNIX平台上使用比较多)的Make工具,C/C++项目经常使用Make工具来管理整个项目的编译,生成 Make使用Shell命令来定 ...

  10. Resharper 8.0 的最实用的功能

    在 8.0 里面.resharper 加入了 插件nuget方式 以前引用resharper插件.都是从新安装,复制进去,或者其他方式.比如resharper xunit  测试 我用xunit 插件 ...