为什么StringBuilder有String的时候?

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

为什么第二个String类?

我在哪里可以学到更多关于StringBuilder

String不允许追加。 您在String上调用的每个方法都将创build一个新对象并将其返回。 这是因为String是不可变的 – 它不能改变它的内部状态。

另一方面, StringBuilder是可变的。 当你调用append(..)它改变内部的char数组,而不是创build一个新的string对象。

因此,有更高的效率:

 StringBuilder sb = new StringBuilder(); for (int i = 0; i < 500; i ++) { sb.append(i); } 

而不是str += i ,这会创build500个新的string对象。

请注意,在这个例子中,我使用了一个循环。 正如helios在注释中注释的那样,编译器自动将expression式如String d = a + b + c为类似的forms

 String d = new StringBuilder(a).append(b).append(c).toString(); 

还要注意,除了StringBuilder之外,还有StringBuilder 。 不同的是前者有同步的方法。 如果你使用它作为局部variables,使用StringBuilder 。 如果碰巧有可能被多个线程访问,请使用StringBuffer (这很less见)

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

 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 

正如你可以看到,性能的差异是显着的。

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

 String s = "Hello"; s = s + "World"; 

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

 StringBuilder sb = new StringBuilder("Hello"); sb.append("World"); 

以上代码将只创build一个对象,因为StringBuilder不是不可变的。

教训:每当需要操纵/更新/附加String时,StringBuilder会比String更高效。

StringBuilder适用于构buildstring。 具体而言,以非常高效的方式构build它们。 String类适用于很多事情,但是当从较小的string部分组装一个新的string时,它实际上有非常糟糕的性能,因为每个新的string都是一个全新的,重新分配的string。 (它是不可变的 )StringBuilder保持相同的顺序并修改它( 可变 )。

效率。

每次连接string时,都会创build一个新的string。 例如:

 String out = "a" + "b" + "c"; 

这将创build一个新的临时string,将“a”和“b”复制到其中以产生“ab”。 然后它创build另一个新的临时string,将“ab”和“c”复制到它中,以产生“abc”。 这个结果被分配out

结果是O( n2 )(二次)时间复杂度的Schlemiel画家algorithm 。

另一方面, StringBuilder允许您就地附加string,根据需要调整输出string的大小。

StringBuilder类是可变的,不像String,它允许你修改string的内容,而不需要创build更多的String对象,当你大量修改一个string时,这可能是一个性能增益。 StringBuilder也有一个名为StringBuffer的对象,它也是同步的,因此非常适合multithreading环境。

String的最大问题是任何使用它的操作都会返回一个新的对象,比如说:

 String s1 = "something"; String s2 = "else"; String s3 = s1 + s2; // this is creating a new object. 

当你处理更大的string时,StringBuilder是很好的。 它可以帮助你提高性能。

这是一篇我觉得很有帮助的文章 。

快速谷歌search可以帮助你。 现在你雇了7个不同的人为你做谷歌search。 🙂

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

Java有String,StringBuffer和StringBuilder:

  • string:它是不可变的

  • StringBuffer:它的可变和ThreadSafe

  • StringBuilder:它的可变但不是ThreadSafe,在Java 1.5中引入

string例如:

 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); } } } 

}

输出:将创build10个不同的string,而不是只有1个string。

 Helloa Helloaa Helloaaa Helloaaaa Helloaaaaa Helloaaaaaa Helloaaaaaaa Helloaaaaaaaa Helloaaaaaaaaa Helloaaaaaaaaaa 

StringBuilder例如:只有一个StringBuilder对象将被创build。

 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); } } }