一、分析 

对于一个字符串进行拼接有三种方法:加号、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. html5 的百度地图连接

    在一些网站上,我们经常会看到一些地址会有一个图标的形式展现,当你点击的时候就会加载一个你点击区域的地图出来,很神奇的一个功能,在之前是没有这样功能的,都是直接写上地址,你要去的话自己找去吧,现在有了这 ...

  2. 使用Eclipse创建Hibernate工程

    创建一个java project项目,加入hibernate的jar包和数据库驱动包,并引入到项目.

  3. Linux系统配置成简单的路由器

    一.两个不同网段的子网相互访问或通信 废话不多说了,直接上图,一目了然吧. 按照如图配置,就可以实现两个不同网段的子网相互通信. 二.连接上网的配置: 如果想让这两个子网,不仅可以相互通信,而且还可以 ...

  4. asp.net实现 EXCEL数据导入到数据库功能

    在项目中经常要用EXCEL导入数据到数据库,提高工作效率. 注意:EXCEL中的第一行不能导入. 下面是源码: IntoExcel.aspx: [csharp] <%@ Page Languag ...

  5. Win7下安装Ubuntu双系统常见问题

    [转自己以前的文章] 导航: ● win7下硬盘安装ubuntu常见问题 ●  win7下u盘安装ubuntu常见问题 吐槽: Ubuntu的安装花了我将近15个小时,网上常见的.不常见的问题基本我都 ...

  6. C# 构造函数如何调用父类构造函数或其他构造函数

    class C : B{    C() : base(5)      // call base constructor B(5)    {  }    C(int i) : this()  // ca ...

  7. select 1 from table where的作用?

    "SELECT 1 FROM identity_approve WHERE identity_num=' " . trim($_POST['IDnumber']) . " ...

  8. C# ORM—Entity Framework 之Database first(数据库优先)&Model First(模型优先)(一)

    一.什么是Entity Framework 1.1 实体框架(EF)是一个对象关系映射器,使.NET开发人员使用特定于域的对象与关系数据.它消除了需要开发人员通常需要编写的大部分数据访问代码.简化了原 ...

  9. mysql操作之二

    特殊数据类型 表约束 表连接 索引 触发器 安全性 DB设计 alter table student modify id int primary key; 主銉不可重复修改 alter table s ...

  10. IIS6中ASP.NET实现对静态文件的授权控制

    后台使用html+ashx+js开发 在VS2008调试并未发现问题 发布到IIS6才发现不需要验证也能访问html文件 解决这个问题配置IIS即可了 方法如下: IIS配置:网站->属性-&g ...