一、分析 

对于一个字符串进行拼接有三种方法:加号、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. tableView Crash

    转自:http://blog.csdn.net/hamasn/article/details/8613593 Assertion failure in -[UITableView _configure ...

  2. MySQL 选择数据库

    MySQL 选择数据库 在你连接到 MySQL 数据库后,可能有多个可以操作的数据库,所以你需要选择你要操作的数据库. 从命令提示窗口中选择MySQL数据库 在 mysql> 提示窗口中可以很简 ...

  3. .net中XML的创建02(linqToXml)

    linqToXml比较的灵活和方便,它是基于函数式编程具体的使用如下:引用程序集using System.Xml.Linq; 1.创建XDocument并设置文档头  XDocument XDoc = ...

  4. Java基础--IO

    1,流的认识和分类 2,Java种处理流的IO类架构 3,字节流和字符流转换 4,NIO的概述 5,Java IO关闭资源 1,流的认识和分类 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的 ...

  5. pugixml使用教程

    pugixml介绍 pugixml是一个高性能.轻量级并且简单易用的xml解析库,支持UTF8 encoding.Little-endian UTF16.Big-endian UTF16.UTF16 ...

  6. C文件函数总结

    1.fopen(打开文件) 表头文件 #include<stdio.h> 定义函数 FILE *fopen(const char * path,const char * mode); pa ...

  7. Open vSwitch在openstackHavana概述

    最近再看Open vSwitch一些东西,我认为openstack官网上对这一块做了一些了解,所以就把这一块翻译出来以供参考,英语不好,翻译得很粗糙. Open vSwitch插件是最有名的核心插件之 ...

  8. ECharts 是一款开源

    ECharts

  9. jquery ajax(5)form表单序列化

    form表单序列化<script type="text/javascript"> $(function(){ $("#send").click(fu ...

  10. HDU1465 第六周L题(错排组合数)

    L - 计数,排列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Descrip ...