18. 【推荐】循环体内,字符串的连接方式,使用StringBuilder的append方法进行扩展。
说明:下例中,反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,
最后通过toString方法返回String对象,造成内存资源浪费。
反例:
String str = "start";
for (int i = 0; i < 100; i++) {
str = str + "hello";
}

1.String是Java中一个不可变的类,所以他一旦被实例化就无法被修改。

不可变类的实例一旦创建,其成员变量的值就不能被修改。这样设计有很多好处,比如可以缓存hashcode、使用更加便利以及更加安全等。

但是,既然字符串是不可变的,那么字符串拼接又是怎么回事呢?

其实,所有的所谓字符串拼接,都是重新生成了一个新的字符串

2.
运算符重载:在计算机程序设计中,运算符重载(英语:operator overloading)是多态的一种。
运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

语法糖:语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语,
指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。
语法糖让程序更加简洁,有更高的可读性。

3.使用+拼接字符串的实现原理

使用+拼接字符串,其实只是Java提供的一个语法糖
Java中的+对字符串的拼接,其实现原理是使用StringBuilder.append

4.concat实现

concat方法的源代码:
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}

这段代码首先创建了一个字符数组,长度是已有字符串和待拼接字符串的长度之和,
再把两个字符串的值复制到新的字符数组中,并使用这个字符数组创建一个新的String对象并返回。

5.StringBuffer和StringBuilder的实现原理

StringBuilder类也封装了一个字符数组: char[] value;
与String不同的是,它并不是final的,所以他是可以修改的。
另外,与String不同,字符数组中不一定所有位置都已经被使用,
它有一个实例变量,表示数组中已经使用的字符个数
int count;

append源码继承了AbstractStringBuilder类中的append方法:
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);//这里传入的参数是增加字符串以后所需要的数组的最小长度
str.getChars(0, len, value, count);
count += len;
return this;
}

append会直接拷贝字符到内部的字符数组中,如果字符数组长度不够,会进行扩展。
StringBuffer和StringBuilder类似,最大的区别就是StringBuffer是线程安全的

StringBuffer的append方法:
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
该方法使用synchronized进行声明,说明是一个线程安全的方法

6.StringUtils.join实现

StringUtils.join的源代码:

public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) {
if (array == null) {
return null;
}
if (separator == null) {
separator = EMPTY;
}

// endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator))
// (Assuming that all Strings are roughly equally long)
final int noOfItems = endIndex - startIndex;
if (noOfItems <= 0) {
return EMPTY;
}

final StringBuilder buf = new StringBuilder(noOfItems * 16);

for (int i = startIndex; i < endIndex; i++) {
if (i > startIndex) {
buf.append(separator);
}
if (array[i] != null) {
buf.append(array[i]);
}
}
return buf.toString();
}

也是通过StringBuilder来实现的。

7.比较

long t1 = System.currentTimeMillis();

String str1 = "hello";
String str2 = "world";
StringBuilder str3 = new StringBuilder();
StringBuffer str4 = new StringBuffer();
for (int i = 0; i < 50000; i++) {
//str1 = str1 + str2;//cost:5325
//str1.concat(str2);//cost:5
//str3.append(str2);//cost:2
str4.append(str2);//cost:3

}
long t2 = System.currentTimeMillis();
System.out.println("cost:" + (t2 - t1));

StringBuilder<StringBuffer<concat<+<StringUtils.join

8.结论

直接使用StringBuilder的方式是效率最高的。因为StringBuilder天生就是设计来定义可变字符串和字符串的变化操作的。
如果不是在循环体中进行字符串拼接的话,直接使用+就好了。

如果在并发场景中进行字符串拼接的话,要使用StringBuffer来代替StringBuilder。

阿里巴巴Java开发手册_不建议在循环体中使用+进行字符串拼接的更多相关文章

  1. 为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

    之前在阅读<阿里巴巴Java开发手册>时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符 ...

  2. 阿里巴巴 Java 开发手册 1.4.0

    一.编程规约(一) 命名风格1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束.反例: _name / __name / $name / name_ / name$ ...

  3. 《阿里巴巴 Java 开发手册》读书笔记

    偶然看到阿里巴巴居然出书了???趁着满减活动(节约节约....)我赶紧买来准备看看,刚拿到的时候掂量了好多下,总觉得商家给我少发了一本书,结果打开才知道..原来这本书这么小.... 编码规范的重要性 ...

  4. 《阿里巴巴Java开发手册》代码格式部分应用——idea中checkstyle的使用教程

    <阿里巴巴Java开发手册>代码格式部分应用--idea中checkstyle的使用教程 1.<阿里巴巴Java开发手册> 这是阿里巴巴工程师送给各位软件工程师的宝典,就像开车 ...

  5. 阿里巴巴Java开发手册——速读记录

    本随笔基于阿里巴巴Java开发手册V1.2,陆陆续续记录一些现阶段能理解的,有启发的内容,并将持续更新 最佳实践——插件使用已经发布为随笔!http://www.cnblogs.com/jiangbe ...

  6. 阿里巴巴 JAVA 开发手册

    阿里巴巴 JAVA 开发手册 1.0.0 阿里巴巴集团技术部 2016.12.7 首次向 Java 业界公开 一. 编程规约(一) 命名规约1. [强制]所有编程相关命名均不能以下划线或美元符号开始, ...

  7. 304902阿里巴巴Java开发手册1.4.0

    转自官网 前言 <阿里巴巴Java开发手册>是阿里巴巴集团技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断完善,系统化地整理成册,回馈给广大开发者.现代软件行业的高速 ...

  8. 【阿里巴巴Java开发手册1.7.0(嵩山版)】编程规约&MySQL 数据库规约

    阿里巴巴Java开发手册1.7.0(嵩山版) 一.编程规约 (一)命名风格 所有命名不得以下划线和$开始和结束. 所有命名不得以拼音或拼音英文混合. 类名使用UpperCamelCase风格. 方法名 ...

  9. 阿里巴巴Java开发手册———个人追加的见解和补充(一)

    先上干货,<阿里巴巴Java开发手册>的下载地址 https://yq.aliyun.com/articles/69327?spm=5176.100239.blogcont69327.15 ...

随机推荐

  1. POJ1001(C++处理大数)

    Exponentiation Time Limit: 500MS   Memory Limit: 10000K Total Submissions: 158025   Accepted: 38470 ...

  2. HDOJ1059(多重部分和问题)

    #include<cstdio> #include<cstring> using namespace std; +; ]; int dp[SIZE]; bool check() ...

  3. ML 徒手系列 最大似然估计

    1.最大似然估计数学定义: 假设总体分布为f(x,θ),X1,X2...Xn为总体采样得到的样本.其中X1,X2...Xn独立同分布,可求得样本的联合概率密度函数为: 其中θ是需要求得的未知量,xi是 ...

  4. 大数据处理之道(十分钟学会Python)

    一:python 简介 (1)Python的由来 Python(英语发音:/ˈpaɪθən/), 是一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个 ...

  5. javascript如何判断手机是什么系统

    做H5页面的时候,经常会用到判断手机是什么系统,根据系统的型号,实现不同的效果,那么如何判断显示页面的手机型号呢? (function(){ var isMobile={ Android:functi ...

  6. Telnet用不了怎么办

    配置了几天的Oracle数据库,忙坏我了,遇到无数问题,其中一个就是Telnet无法使用: 经过检查发现,其实是这个软件没有安装,取程序里面找到之后,加装这个组件,完成安装. 但是还是不能用,发现服务 ...

  7. strstr strchr strrchr strrstr

    通过函数的定义来区分: 1.strstr: 返回子串出现的第一次位置 char *strstr(const char *haystack, const char *needle) 可见,strstr函 ...

  8. 孙鑫VC学习系列教程

    教程简介 1.循序渐进 从Win32SDK编程开始讲解,帮助大家理解掌握Windows编程的核心 -- 消息循环机制. 2.通俗易懂 编程语言枯燥难懂,然而通过孙鑫老师形象化的讲解,Windows和M ...

  9. Learning Python 003 缩进

    Python 缩进 Python的代码中不使用{}大括号来来表示一个代码块,而是使用缩进方式.像下面这段代码: # print absolute value of an integer: a = 10 ...

  10. linux date用法

    读者可以设定特定的格式,格式设定规则:一个加号后接数个标记,每个标记中都有%,其中可用的标记列表和说明如下:  %n : 下一行 %t : 跳格 %H : 小时(00..23) %I : 小时(01. ...