Java 字符串与字符串缓冲区。点子
Intellij Idea提供以下替代方案:Java 字符串与字符串缓冲区。点子,java,performance,intellij-idea,stringbuffer,Java,Performance,Intellij Idea,Stringbuffer,Intellij Idea提供以下替代方案: StringBuffer sb = new StringBuffer(); sb.append("Name=").append(name).append(", name2=").append(name2).append(", list=").append(list); return sb.toString(); 致: 据我所知,它的效率较低(可变/不可变)。 那么,有什么更好呢?Java编译器会自动将关注的字符串更改为StringBuilders-
StringBuffer sb = new StringBuffer();
sb.append("Name=").append(name).append(", name2=").append(name2).append(", list=").append(list);
return sb.toString();
致:
据我所知,它的效率较低(可变/不可变)。
那么,有什么更好呢?Java编译器会自动将关注的字符串更改为StringBuilders->您可以在.class文件中看到它们 因此,java编译器也是如此 提示出现在您面前,因为IntelliJ假定连接的字符串对于程序员来说更容易阅读 例如: 编辑器中的toString方法: XYZ.java:
public class XYZ {
private String x;
private int y;
private Integer z;
@Override
public String toString() {
return "XYZ [x=" + x + ", y=" + y + ", z=" + z + "]";
}
}
toString方法生成的字节码:
XYZ.class:
public toString()Ljava/lang/String;
L0
LINENUMBER 9 L0
NEW java/lang/StringBuilder
DUP
LDC "XYZ [x="
INVOKESPECIAL java/lang/StringBuilder.<init> (Ljava/lang/String;)V
ALOAD 0
GETFIELD at/gv/brz/jus3/as/dto/XYZ.x : Ljava/lang/String;
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
LDC ", y="
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ALOAD 0
GETFIELD at/gv/brz/jus3/as/dto/XYZ.y : I
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
LDC ", z="
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ALOAD 0
GETFIELD at/gv/brz/jus3/as/dto/XYZ.z : Ljava/lang/Integer;
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/Object;)Ljava/lang/StringBuilder;
LDC "]"
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ARETURN
L1
LOCALVARIABLE this Lat/gv/brz/jus3/as/dto/XYZ; L0 L1 0
MAXSTACK = 3
MAXLOCALS = 1
}
publictostring()Ljava/lang/String;
L0
9号线L0
新java/lang/StringBuilder
重复
LDC“XYZ[x=”
调用特殊的java/lang/StringBuilder。(Ljava/lang/String;)V
阿洛德0
GETFIELD位于/gv/brz/jus3/as/dto/XYZ.x:Ljava/lang/String;
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
最不发达国家“,y=”
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
阿洛德0
GETFIELD位于/gv/brz/jus3/as/dto/XYZ.y:I
invokeVirtualJava/lang/StringBuilder.append(I)Ljava/lang/StringBuilder;
最不发达国家“,z=”
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
阿洛德0
GETFIELD位于/gv/brz/jus3/as/dto/XYZ.z:Ljava/lang/Integer;
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
最不发达国家“]
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokeVirtualJava/lang/StringBuilder.toString()Ljava/lang/String;
轮回
L1
本地变量此Lat/gv/brz/jus3/as/dto/XYZ;L0 l10
MAXSTACK=3
最大局部数=1
}
如您所见,编译器会自动生成一个StringBuilder。因此,只有在使用容量参数生成StringBuilder时,才需要使用显式StringBuilder。第二个StringBuilder编译为与第一个相同的字节码,只是它使用了非同步的
StringBuilder
而不是同步的StringBuffer
。所以它不仅可读性更强,而且速度更快。我会选择第二个
在循环中串联时,使用StringBuilder
非常有用,以避免创建许多临时String
对象:
String result = "";
for (String element : array) {
result += element;
}
应该由
StringBuilder builder = new StringBuilder();
for (String element : array) {
builder.append(element);
}
String result = builder.toString();
@塞巴斯蒂安:噢,从长远来看,这不是性能最好的代码。但它大致相当于OP的功能(除了使用
StringBuilder
而不是StringBuffer
)……理想情况下,提供一个可能保存结果的字符串生成器的大小,因此您不会从默认的16个字符的大小获得所有这些重新分配。
StringBuilder builder = new StringBuilder();
for (String element : array) {
builder.append(element);
}
String result = builder.toString();