Tips
书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于Java 9 API中的,因此JDK 最好下载 JDK 9以上的版本。java
字符串链接操做符(+)是将几个字符串组合成一个字符串的便捷的方法。对于生成单行输出或构造一个小的、固定大小的对象的字符串表示形式,它是能够的,可是它不能伸缩。重复使用字符串链接运算符来链接n个字符串须要n的平方级的时间。这是因为字符串是不可变的这一事实致使的结果(条目 17)。当链接两个字符串时,须要复制这两个字符串的内容。git
例如,考虑这个方法,它经过为每一个项目重复链接一行来构造帐单语句的字符串表示:github
// Inappropriate use of string concatenation - Performs poorly! public String statement() { String result = ""; for (int i = 0; i < numItems(); i++) result += lineForItem(i); // String concatenation return result; }
若是项的数量很大,则该方法的性能很是糟糕。为了达到可接受的性能,使用StringBuilder
代替String来存储正在构建的语句:数组
public String statement() { StringBuilder b = new StringBuilder(numItems() * LINE_WIDTH); for (int i = 0; i < numItems(); i++) b.append(lineForItem(i)); return b.toString(); }
自Java 6以来,为了使字符串链接更快,已经作了大量工做,可是这两个方法在性能上的差别仍然很大:若是numItems返回100个元素,每一个lineForItem返回一个固定长度为80个字符串,那么在个人机器上运行,第二个方法的速度是第一个方法的6.5倍。因为第一种方法在项目数量上是平方级增加的,而第二种方法是线性的,因此随着项目数量的增长,性能差别会变得愈来愈大。注意,第二个方法预先分配了一个足够大的StringBuilder来保存整个结果,从而消除了自动增加的须要。即便使用默认大小的StringBuilder,它仍然比第一个方法快5.5倍。app
道理很简单:除非性能可有可无,不然不要使用字符串链接操做符组合多个字符串。而是使用StringBuilder的append方法。或者,使用字符数组,或者一次处理一个字符串,而不是把它们组合起来。性能