为什么有人会String
用完StringBuilder
。
我知道以下事实:
那么,为什么有人会使用String
如果StringBuilder
已经存在呢?
StringBuilder是可变的,而String是不可变的。不可变意味着它不会更改,因此您关于不同步的观点毫无意义-没有同步的可能更改。
简而言之,如果您不需要StringBuilders的其他功能(这在字符串中很常见),则String的效率更高。它还具有JVM中高度优化的特殊处理功能,这是Java中其他对象所没有的。
特定于字符串的最优化的示例(字符串池)使字符串的行为像常量一样,因为可以在整个应用程序中自动共享同一实例,从而节省了内存和时间。对于其他对象,这是不可能自动实现的,对于可变对象,通常甚至都不希望这样做。与定制池相比,String池已被证明可以容纳更多具有更好性能的对象。只使用一个String实例的全部实例来提高性能的过程称为string interning。
由于您仅使用一个实例,因此在比较时,只需比较参考。对于每个StringBuilder实例,您都需要评估对象的内容才能做到这一点。Stringbuilder使用Array作为支持对象,并且必须遍历该Array才能获取其内容,这要花很多钱。这假设您对字符串内容感兴趣,而不是对象实例,这在String / StringBuilder / StringBuffer中几乎总是这样。
比较String和StringBuilder内容的简单性能测试:
public class CompTest {
// fastest way to compare StringBuilder contents according to
// http://stackoverflow.com/questions/11007387/what-is-an-efficient-way-to-compare-stringbuilder-objects
static boolean contentEquals(StringBuilder sb1, StringBuilder sb2) {
if (sb1.length() != sb2.length()) return false;
for (int i = 0, len = sb1.length(); i < len; i++) {
if (sb1.charAt(i) != sb2.charAt(i)) return false;
}
return true;
}
public static void main(String args[]) {
StringBuilder fooSb = new StringBuilder("foo");
StringBuilder barSb = new StringBuilder("foo");
String foo = "foo";
String bar = "foo";
System.out.println(foo.equals(bar));
// returns true
System.out.println(fooSb.equals(barSb));
// returns false, so cannot be used to check contents
System.out.println(contentEquals(fooSb,barSb));
// returns true
long time;
time = System.currentTimeMillis();
for (int i = 0; i < 2000000000; i++) {
if (foo.equals(bar)) continue;
}
System.out.println("str comparisons took " + (System.currentTimeMillis() - time) + " ms");
time = System.currentTimeMillis();
for (int i = 0; i < 2000000000; i++) {
if (contentEquals(fooSb,barSb)) continue;
}
System.out.println("sb comparisons took " + (System.currentTimeMillis() - time) + " ms");
/* repeat the test as we know JVM is warmed up by now */
time = System.currentTimeMillis();
for (int i = 0; i < 2000000000; i++) {
if (foo.equals(bar)) continue;
}
System.out.println("str comparisons took " + (System.currentTimeMillis() - time) + " ms");
time = System.currentTimeMillis();
for (int i = 0; i < 2000000000; i++) {
if (contentEquals(fooSb,barSb)) continue;
}
System.out.println("sb comparisons took " + (System.currentTimeMillis() - time) + " ms");
}
}
结果:
true
false
true
str comparisons took 1244 ms
sb comparisons took 11530 ms
str comparisons took 1231 ms
sb comparisons took 12098 ms
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句