一、分析 

对于一个字符串进行拼接有三种方法:加号、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. 64位Window操作系统下,Orcal数据访问服务器端和客户端版本对应与通讯问题

    最近做一个小系统,需要在客户现场搭建数据库环境.之前我们一直访问的是公司的一个测试库,现在需要在现场开发,现场的Orcal服务器是12C ,我们本不打算重装服务器端orcal,故将我们自己电脑的orc ...

  2. 判断iPhone和iPad 判断设备版本

    //判断iPhone和iPad #define IS_IPHONE (!IS_IPAD) #define IS_IPAD (UI_USER_INTERFACE_IDIOM() != UIUserInt ...

  3. Object Storage(Swift)安装过程——Havana

    自从看了Havana安装文档有关Swift的安装一节,发现H版的安装过程与以前还是有些差别的.不过大致过程还是那些.下面简单介绍下我们安装的过程吧,具体请参考官方文档http://docs.opens ...

  4. css3之box-sizing

    css盒子模型中包括几种重要的属性,包括margin.border.padding以及content.但浏览器对其盒子模型的解释则有所不痛,启用标准模式还是IE(怪)模式是与当前页面的文档声明相关的. ...

  5. git操作(强烈推荐)

    一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以 ...

  6. php字符串常见面试题

    >> 本文固定链接: http://php.ncong.com/mianshi/mianshiti_string.html >> 转载请注明: 恩聪php 2014年09月02 ...

  7. 百度地图api窗口信息自定义

    百度地图加载完后,完全可以用dom方法操作,比较常用的就是点击mark的弹窗,利用jQuery可以很快的创建弹窗,需要注意的就是地图都是异步加载,所以绑定时间要用 jQuery 事件 - delega ...

  8. C# Ini文件操作

    在开源中国看到的操作ini文件的,写的还不看,留着以后用 using System; using System.IO; using System.Runtime.InteropServices; us ...

  9. Oracle 游标使用全解(转)

    转自:http://www.cnblogs.com/sc-xx/archive/2011/12/03/2275084.html 这个文档几乎包含了oracle游标使用的方方面面,全部通过了测试 -- ...

  10. Java笔记-快速失败and安全失败

    参考资料:http://blog.csdn.net/chenssy/article/details/38151189 快速失败 fail-fast 安全失败 fail-safe java.util包下 ...