public class Test { List<String> list = new ArrayList<>(); @Before public void init(){ IntStream.range(0, 100000).forEach((index) -> { list.add("str" + index); }); } @org.junit.Test public void test1() { String ss = ""; long startTime = System.currentTimeMillis(); for (String s : list) { ss += s; } System.out.println(System.currentTimeMillis() - startTime); } @org.junit.Test public void test2() { String ss = ""; long startTime = System.currentTimeMillis(); for (String s : list) { ss=ss.concat(s); } System.out.println(System.currentTimeMillis() - startTime); } @org.junit.Test public void test3() { StringBuilder ss = new StringBuilder(); long startTime = System.currentTimeMillis(); for (String s : list) { ss.append(s); } System.out.println(System.currentTimeMillis() - startTime); } @org.junit.Test public void test4() { long startTime = System.currentTimeMillis(); StringUtils.join(list); System.out.println(System.currentTimeMillis() - startTime); } @org.junit.Test public void test5() { StringBuffer ss = new StringBuffer(); long startTime = System.currentTimeMillis(); for (String s : list) { ss.append(s); } System.out.println(System.currentTimeMillis() - startTime); } }
First: 33809
Second: 8851
Third: 6
Type 4: 12
Type 5: 7
Performance: StringBuilder > StringBuffer > stringutils. Join > concat >+
Then from the source level analysis
StringBuilder:

Each string concatenation is just to extend the internal char array and only produce one final string, so this is the most efficient
StringBuffer:

Compared with StringBuilder, it only adds an additional synchronized, so it is not much different in the case of single thread
StringUtils.join:


It can be seen that the inner part is still implemented by StringBuilder, but there are more separators in each cycle, so it's a little slower, but it's not much, and the time is an order of magnitude
concat:

It can be seen that each connection will generate a string, so the efficiency is very low
+:
Because it is an overloaded operator, the source code cannot be found, but the result shows that the efficiency is the lowest