我知道这里发布了很多类似的问题,但这些问题并没有真正回答我的问题。
我只是想知道为什么StringBuilder
比使用+
运算符的字符串连接快得多。尽管+
运算符内部是使用StringBuffer
或StringBuilder
实现的?
public void shortConcatenation(){
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis()-startTime<=1000){
character+="Y";
}
System.out.println("short :"+character.length());
}
////使用String builder
public void shortConcatenation2(){
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
while (System.currentTimeMillis()-startTime<=1000){
sb.append("Y");
}
System.out.println("string builder short :"+sb.length());
}
提前致谢!
答案 0 :(得分:9)
你了解它的内部运作方式吗?
每次执行stringA += stringB;
时,都会创建一个新字符串,并将其分配给stringA,这样它将消耗内存(新字符串实例!)和时间(复制旧字符串+另一个字符串的新字符)。
StringBuilder
将在内部使用一组字符,当您使用.append()
方法时,它会执行以下操作:
System.arraycopy
来复制数组中字符串的字符。就我个人而言,我认为每次分配一个新字符串(创建一个新的字符串实例,放置字符串等)在内存和速度方面可能非常广泛(特别是在/等等时)。 / p>
在您的示例中,使用StringBuilder
更好,但如果您需要(示例)简单的内容,例如.toString()
public String toString() {
return StringA + " - " + StringB;
}
没有区别(好吧,在这种情况下,你最好避免使用StringBuilder开销,这在这里没用。)
答案 1 :(得分:5)
java中的字符串是不可变的。这意味着对字符串进行操作的方法不能更改字符串的值。使用+ =进行字符串连接的工作原理是为一个全新的字符串分配内存,该字符串是前两个字符串的串联,并用这个新字符串替换引用。每个新的连接都需要构造一个全新的String对象。
相反,StringBuilder和StringBuffer类是作为可变字符序列实现的。这意味着当您将新的字符串或字符附加到StringBuilder时,它只是更新其内部数组以反映您所做的更改。这意味着只有当字符串超过StringBuilder中已存在的缓冲区时才会分配新内存。
答案 2 :(得分:0)
我可以列出一个非常好的示例来理解相同的内容(我是说我觉得这是一个很好的示例),请检查此处来自leetcode的代码问题:https://leetcode.com/problems/remove-outermost-parentheses/ 1:使用字符串 public String removeOuterParentheses(String S){
String a="";
int num=0;
for(int i=0;i<S.length()-1;i++) {
if(S.charAt(i)=='(' && num++>0) {
a+="(";
}
if(S.charAt(i)==')' && num-->1) {
a+=")";
}
}
return a;
}
,现在,使用StringBuilder。 public String removeOuterParentheses(String S){
StringBuilder sb = new StringBuilder();
int a=0;
for(char ch : S.toCharArray()) {
if(ch=='(' && a++>0) sb.append('(');
if(ch==')' && a-->1) sb.append(')');
}
return sb.toString();
}
两者的表现差异很大, 第一个提交使用String,而第二个提交使用StringBuilder。
如上所述,理论是相同的。按属性的字符串是不可变且同步的,即其状态无法更改。第二个。由于每当使用串联函数或“ +”时都会创建新的内存分配,因此开销很大。它会消耗大量的堆,并且会变慢。相比之下,StringBuilder是可变的,它只会追加并不会在消耗的内存上创建过载。
希望这会有所帮助。