为什么StringBuilder有String?

an0*_*00b 75 java string stringbuilder

我刚刚StringBuilder第一次遇到并且感到惊讶,因为Java已经有一个非常强大的String类允许追加.

为什么选择String二等?

我在哪里可以了解更多信息StringBuilder

Boz*_*zho 158

String不允许附加.您在a上调用的每个方法都会String创建一个新对象并将其返回.这是因为String它是不可变的 - 它不能改变它的内部状态.

另一方面StringBuilder是可变的.调用append(..)它时会改变内部char数组,而不是创建新的字符串对象.

因此,拥有以下内容更有效:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 500; i ++) {
    sb.append(i);
}
Run Code Online (Sandbox Code Playgroud)

而不是str += i,它将创建500个新的字符串对象.

请注意,在示例中我使用循环.正如helios在评论中指出的那样,编译器会自动将表达式转换String d = a + b + c为类似的表达式

String d = new StringBuilder(a).append(b).append(c).toString();
Run Code Online (Sandbox Code Playgroud)

还需要注意的是有StringBufferStringBuilder.不同之处在于前者具有同步方法.如果将其用作局部变量,请使用StringBuilder.如果它可能被多个线程访问,请使用StringBuffer(这是罕见的)

  • +1.您可以添加:"因此StrungBuilder寻找性能"和"Java编译器使用新的StringBuilder(A).append(B).append(C).toString()替换A + B + C等表达式,以避免对象创建性能处罚":) (22认同)

Ami*_*far 59

这是一个具体的例子,为什么 -

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
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,性能差异很大.

  • 这确实解释了**为什么StringBuilder有String?**这不解释**为什么StringBuilder如此之快.**但这不是问题.所以这是一个有效的答案. (23认同)
  • 我认为为了使比较公平,你应该包括在最后执行`s = sb.ToString();`的时间,所以至少你在两个例子中都做了同样的事情(结果是`字符串`). (12认同)
  • @krmby - 同意.回答为什么真正意味着另一个问题. (2认同)

Ume*_*cha 19

String类是不可变的,而StringBuilder是可变的.

String s = "Hello";
s = s + "World";
Run Code Online (Sandbox Code Playgroud)

上面的代码将创建两个对象,因为String是不可变的

StringBuilder sb = new StringBuilder("Hello");
sb.append("World");
Run Code Online (Sandbox Code Playgroud)

上面的代码只会创建一个对象,因为StringBuilder不是不可变的.

课程:每当需要多次操作/更新/追加String时,请将StringBuilder作为与String相比的高效.


Rex*_*x M 8

StringBuilder用于构建字符串.具体来说,以非常高效的方式构建它们.String类适用于很多东西,但是当用较小的字符串部分组装新字符串时,它实际上具有非常糟糕的性能,因为每个新字符串都是一个全新的,重新分配的字符串.(它是不可变的)StringBuilder在原地保持相同的顺序并修改它(可变).


Car*_*osZ 5

StringBuilder类是可变的,与String不同,它允许您修改字符串的内容而无需创建更多String对象,当您大量修改字符串时,这可以提高性能。还有一个名为StringBuffer的StringBuilder副本,它也是同步的,因此非常适合多线程环境。

String的最大问题是您对其执行的任何操作都将始终返回一个新对象,例如:

String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.
Run Code Online (Sandbox Code Playgroud)


小智 5

准确地说,StringBuilder 添加所有字符串的时间复杂度为 O(N),而添加 String 的时间复杂度为 O(N^2)。检查源代码,这是通过保留可变字符数组在内部实现的。StringBuilder 使用数组长度复制技术来实现摊销O(N^2) 性能,但代价可能是所需内存加倍。你可以在最后调用trimToSize来解决这个问题,但通常StringBuilder对象只是暂时使用。您可以通过对最终字符串大小提供良好的起始猜测来进一步提高性能。