当前位置: 首页 > 科技观察

为什么Java8不再需要StringBuilder来拼接字符串

时间:2023-03-13 11:31:52 科技观察

在Java开发者中,字符串拼接的高资源消耗常常是一个热门话题。下面深入讨论一下为什么会占用高资源。在Java中,String对象是不可变的,这意味着它一旦创建就无法更改。所以当我们连接字符串时,一个新字符串被创建,旧字符串被垃圾收集器标记。如果我们处理数百万个字符串,那么我们会生成数百万个额外的字符串以供垃圾收集器处理。虚拟机的底层在连接字符串时执行许多操作。用于连接字符串的最直接的点运算符是String#concat(String)操作。publicStringconcat(Stringstr){intotherLen=str.length();if(otherLen==0){returnthis;}intlen=value.length;charbuf[]=Arrays.copyOf(value,len+otherLen);str.getChars(buf,len);returnnewString(buf,true);}publicstaticchar[]copyOf(char[]original,intnewLength){char[]copy=newchar[newLength];System.arraycopy(original,0,copy,0,Math.min(original.length,newLength));returncopy;}voidgetChars(chardst[],intdstBegin){System.arraycopy(value,0,dst,dstBegin,value.length);}可以看到创建了一个字符数组,length它是现有字符和连接字符的长度之和。然后,将它们的值复制到新的字符数组中。***,用这个字符数组创建一个String对象并返回。所以这些操作很多,你计算一下,你会发现是O(n^2)的复杂度。为了解决这个问题,我们使用StringBuilder类。这就像可变的String类。拼接方法帮助我们避免不必要的重复。它的复杂度为O(n),远优于O(n^2)。但是,Java8默认使用StringBuilder来连接字符串。Java8的文档指出:为了提高字符串连接的性能,Java编译器可以使用StringBuffer类或类似技术来减少在计算表达式时创建中间String对象。Java编译器会处理这种情况:代码:0:aload_01:invokespecial#1//Methodjava/lang/Object."":()V4:returnpublicstaticvoidmain(java.lang.String[]);代码:0:ldc#2//StringHello2:astore_13:new#3//classjava/lang/StringBuilder6:dup7:invokespecial#4//Methodjava/lang/StringBuilder."":()V10:aload_111:invokevirtual#5//Methodjava/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;14:ldc#6//Stringworld16:invokevirtual#5//Methodjava/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/字符串生成器;19:invokevirtual#7//Methodjava/lang/StringBuilder.toString:()Ljava/lang/String;22:astore_123:return}正如你在这些字节码中看到的,使用了StringBuilder。所以我们不再需要在Java8中使用StringBuilder类。翻译链接:http://www.codeceo.com/article/why-java8-not-use-stringbuilder.html英文原文:WeDon'tNeedStringBuilderfor不再串联