为什么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); } } }