String直接相加,StringBuffer.append(), StringBulider.append(), guava中Joiner.on.join()
首先探讨时间:
/**
* Created with IntelliJ IDEA. User: jianjun.yu Date: 14-8-11 Time: 下午6:33 To change this template use File | Settings |
* File Templates.
*/
public class StringBulidTest {
public static void main(String[] args) {
List<String> list = Lists.newArrayList();
for (Integer i = 0; i < 100000; i++) {
list.add(String.valueOf(i));
}
String addStr = null;
long begin = System.currentTimeMillis();
for (String str : list) {
addStr += str;
}
long end = System.currentTimeMillis();
System.out.println("直接str + 耗时:" + String.valueOf(end - begin));
StringBuilder stringBuilder = new StringBuilder();
begin = System.currentTimeMillis();
for (String str : list) {
stringBuilder.append(str);
}
end = System.currentTimeMillis();
System.out.println("StringBuilder.append()耗时:" + String.valueOf(end - begin));
StringBuffer stringBuffer = new StringBuffer();
begin = System.currentTimeMillis();
for (String str : list) {
stringBuffer.append(str);
}
end = System.currentTimeMillis();
System.out.println("StringBuffer.append()耗时:" + String.valueOf(end - begin));
begin = System.currentTimeMillis();
Joiner.on("").join(list);
end = System.currentTimeMillis();
System.out.println("Joiner.on().join()耗时:" + String.valueOf(end - begin));
}
}
测试结果:
直接str + 耗时:10412
StringBuilder.append()耗时:14
StringBuffer.append()耗时:18
Joiner.on().join()耗时:27
str+耗时最慢,原因见上篇博客《细说String》里面已说明,
stringbuffer中用了大量的synchronized对象锁,stringbuffer与 stringbuider的底层实现唯一区别就在于stringbuffer为线程安全,
都继成了 AbstractStringBuilder
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
public synchronized StringBuffer append(char[] str) {
super.append(str);
return this;
}
public AbstractStringBuilder append(char[] str) {
int len = str.length;
ensureCapacityInternal(count + len);
System.arraycopy(str, 0, value, count, len);
count += len;
return this;
}
}
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
public StringBuilder append(char[] str) {
super.append(str);
return this;
}
}
abstract class AbstractStringBuilder implements Appendable, CharSequence {
public AbstractStringBuilder append(char[] str) {
int len = str.length;
ensureCapacityInternal(count + len);
System.arraycopy(str, 0, value, count, len);
count += len;
return this;
}
}
Joiner.on().join()其实在每个对象之间都多加了一个字符串对象(间隔符)性能也会慢一点。
最后探讨空间:
参看stringbuffer与stringbulider源码实现, 当字符串大到一定程度时,二者都会出现扩容的情况, 类似C++里面的vector.
这样的话, 当string大到一定程度时,会造成严重的空间消耗。
解决之道: 类试hashmap,预先估计strng大小。