我第一次遇到StringBuilder
并且感到惊讶,因为Java已经有一个非常强大的String
类允许追加。
为什么选择第二个String
?
我在哪里可以了解有关StringBuilder
的更多信息?
答案 0 :(得分:153)
String
不允许附加。您在String
上调用的每个方法都会创建一个新对象并将其返回。这是因为String
是不可变的 - 它不能改变其内部状态。
另一方面,StringBuilder
是可变的。当你调用append(..)
时,它会改变内部char数组,而不是创建一个新的字符串对象。
因此更有效率:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 500; i ++) {
sb.append(i);
}
而不是str += i
,这将创建500个新的字符串对象。
请注意,在示例中我使用循环。正如helios在评论中指出的那样,编译器会自动将String d = a + b + c
等表达式转换为类似
String d = new StringBuilder(a).append(b).append(c).toString();
另请注意,StringBuffer
除StringBuilder
外还有StringBuilder
。不同之处在于前者具有同步方法。如果将其用作局部变量,请使用StringBuffer
。如果它可能被多个线程访问,请使用{{1}}(这是罕见的)
答案 1 :(得分:56)
以下是为什么 -
的具体示例int total = 50000;
String s = "";
for (int i = 0; i < total; i++) { s += String.valueOf(i); }
// 4828ms
StringBuilder sb = new StringBuilder();
for (int i = 0; i < total; i++) { sb.append(String.valueOf(i)); }
// 4ms
正如您所看到的,性能差异很大。
答案 2 :(得分:18)
String类是不可变的,而StringBuilder是可变的。
String s = "Hello";
s = s + "World";
上面的代码将创建两个对象,因为String是不可变的
StringBuilder sb = new StringBuilder("Hello");
sb.append("World");
上面的代码只会创建一个对象,因为StringBuilder不是不可变的。
课程:每当需要多次操作/更新/追加String时,请将StringBuilder作为与String相比的效率。
答案 3 :(得分:8)
StringBuilder用于构建字符串。具体来说,以非常高效的方式构建它们。 String类适用于很多东西,但是当用较小的字符串部分组装新字符串时,它实际上具有非常糟糕的性能,因为每个新字符串都是一个全新的,重新分配的字符串。 (它是 immutable )StringBuilder在原地保留相同的序列并对其进行修改( mutable )。
答案 4 :(得分:4)
StringBuilder类是可变的,与String不同,它允许您修改字符串的内容,而无需创建更多的String对象,这在您大量修改字符串时可以获得性能提升。 StringBuilder还有一个名为StringBuffer的对应项,它也是同步的,因此非常适合多线程环境。
String的最大问题是你用它做的任何操作总会返回一个新对象,比如说:
String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.
答案 5 :(得分:3)
效率。
每次连接字符串时,都会创建一个新字符串。例如:
String out = "a" + "b" + "c";
这会创建一个新的临时字符串,将“a”和“b”复制到其中以产生“ab”。然后它创建另一个新的临时字符串,将“ab”和“c”复制到其中,以产生“abc”。然后将此结果分配给out
。
结果是Schlemiel the Painter's algorithm的O(n²)(二次)时间复杂度。
另一方面, StringBuilder
允许您就地附加字符串,根据需要调整输出字符串的大小。
答案 6 :(得分:2)
答案 7 :(得分:2)
准确地说,添加所有字符串的StringBuilder是O(N),而添加字符串是O(N ^ 2)。检查源代码,这是通过保持可变数组的字符在内部实现的。 StringBuilder使用数组长度复制技术来实现 ammortized O(N ^ 2)性能,代价是可能会使所需内存翻倍。你可以在最后调用trimToSize来解决这个问题,但通常只会暂时使用StringBuilder对象。您可以通过在最终字符串大小上提供良好的初始猜测来进一步提高性能。
答案 8 :(得分:1)
Java有String,StringBuffer和StringBuilder:
字符串:不可变的
StringBuffer:它的Mutable和ThreadSafe
StringBuilder:它的可变但不是ThreadSafe,在Java中引入 1.5
字符串例如:
public class T1 {
public static void main(String[] args){
String s = "Hello";
for (int i=0;i<10;i++) {
s = s+"a";
System.out.println(s);
}
}
}
}
输出:将创建10个不同的字符串,而不仅仅是1个字符串。
Helloa
Helloaa
Helloaaa
Helloaaaa
Helloaaaaa
Helloaaaaaa
Helloaaaaaaa
Helloaaaaaaaa
Helloaaaaaaaaa
Helloaaaaaaaaaa
StringBuilder例如:将只创建1个StringBuilder对象。
public class T1 {
public static void main(String[] args){
StringBuilder s = new StringBuilder("Hello");
for (int i=0;i<10;i++) {
s.append("a");
System.out.println(s);
}
}
}
答案 9 :(得分:-1)
String和StringBuilder都是Java中的类,但是区别是String是不可变的,而StringBuilders是可变的。某些操作不是String提供的,而StringBuilder提供了。以下是一些StringBuilder方法:
要在String上使用StringBuilder方法,必须将String作为参数传递给StringBuilder构造函数,它将创建一个StringBuilder实例
String s = "Your String";
StringBuilder sb = new StringBuilder(s);
然后,您可以在StringBuilder实例sb上使用以下StringBuilder方法