String的不可变,StringBuilder.append方法和String.concat

String.concat

对String字符串进行拼接的方法,我们通常用的“+”拼接字符串,效率相比concat更低,其内部实现方式类似于new StringBuilder().append,每次拼接都会创建一个StringBuilder对象。

concat方法的核心逻辑:创建长度为str.length+str2.length的char数组,通过Arrays.copyOf创建,该方法可以指定一个初始字符数组,选择为str.toCharArray,然后通过System.arraycopy方法将第二个字符数组填到初始字符数组中,最后通过new String将字符数组返回为String

1 joinStr.concat(joinStr2);
2 int otherLen = joinStr2.length();
3 int len = joinStr.length();
4 char buf[] = Arrays.copyOf(joinStr.toCharArray(), len + otherLen);
5 System.arraycopy(joinStr2.toCharArray(), 0, buf, len, joinStr2.length());
6 System.out.println("joinStr3:"+new String(buf));

 StringBuilder.append

append核心逻辑:通过Arrays.copyOf创建长度为sb1.length+sb2.length的新字符数组,再通过String.getChars将sb2塞入到新字符数组中,再将当前StringBuilder的count变量改为扩展后的长度,最后直接return this,并没有通过new String返回

1 value = Arrays.copyOf(value, newCapacity(minimumCapacity));
2 str.getChars(0, len, value, count);
3 count += len;

为什么String.concat需要new String返回新创建的char数组,而StringBuilder.append不需要,看源码可以看到String内部的char数组,也就是value,被private final修饰了,StringBuilder内部的没有,这代表String的value为一个私有的不可变的常量(反射可破坏),所以每次修改都需要new String对象,而StringBuilder.append每次都是修改的当前对象值。

由于Sting拼接字符串每次都创建新对象,所以效率低于append,在数据量小的情况下可以使用String,比较方便直接,而在大量数据的情况下需要使用append。StringUtils的join将列表拼成字符串,内部也是通过append实现的,也比较推荐。

posted @ 2024-02-16 15:07  leviH  阅读(8)  评论(0编辑  收藏  举报