将集合元素拼接成 逗号连接的字符串有多种方式,除了自己写循环外,常用工具包有如下几种。
1.Guava包中的Joiner.on(",").join()
2.Apache Commons 包中的 StringUtils.join()
3.JDK中的String.join()
用法:
@Test
public void testJoin() {
final String numberList ="One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten";
int times =10;
StringBuilder stringBuilder =new StringBuilder();
while (times-- >0) {
stringBuilder.append(numberList).append(",");
}
String src = stringBuilder.toString();
String[] split = src.split(",");
long start1 = System.currentTimeMillis();
for (int i =0; i <1000000; i++) {
String join = Joiner.on(",").join(split);
}
System.err.println(System.currentTimeMillis() - start1);
/**
* StringUtils.join 通过控制内部StringBuilder初始化的容量大小来优化StringBuild的扩容过程
*/
long start2 = System.currentTimeMillis();
for (int i =0; i <1000000; i++) {
String join = StringUtils.join(split, ",");
}
System.err.println(System.currentTimeMillis() - start2);
long start3 = System.currentTimeMillis();
for (int i =0; i <1000000; i++) {
String join = String.join(",", split);
}
System.err.println(System.currentTimeMillis() - start3);
}
性能对比:
此处对一个 含有1000个元素的数组进行拼接,每个循环100万次,执行时间如下:
Guava Joiner.on(",").join() 耗时20937ms
Apache Commons 包中的 StringUtils.join() 耗时 15885ms
JDK中的String.join() 耗时21314ms
发现Apache Commons 包中的 StringUtils.join操作最快。
查看源码,分析下原因
StringUtils.join()源码
public static Stringjoin(final Object[] array, final char separator, final int startIndex, final int endIndex) {
if (array ==null) {
return null;
}
final int noOfItems = endIndex - startIndex;
if (noOfItems <=0) {
return EMPTY;
}
final StringBuilder buf =new StringBuilder(noOfItems);
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时,通过设置初始容量大小,减少了扩容次数,增加了性能。
查看源码发现,当操作集合类型时,仍然通过设置较大的初始容量来提高效率。
public static Stringjoin(final Iterator iterator, final String separator) {
// handle null, zero and one elements before building a buffer
if (iterator ==null) {
return null;
}
if (!iterator.hasNext()) {
return EMPTY;
}
final Object first = iterator.next();
if (!iterator.hasNext()) {
return Objects.toString(first, "");
}
// two or more elements
final StringBuilder buf =new StringBuilder(STRING_BUILDER_SIZE); // Java default is 16, probably too small
if (first !=null) {
buf.append(first);
}
while (iterator.hasNext()) {
if (separator !=null) {
buf.append(separator);
}
final Object obj = iterator.next();
if (obj !=null) {
buf.append(obj);
}
}
return buf.toString();
}