为什么有人会./testConcat
line pdb8mhtA
pdbfile pdb8mhtA.pdb
使用String
。
我知道以下事实:
那么,如果StringBuilder
已经存在,为什么有人会使用String
?
答案 0 :(得分:1)
StringBuilder是 mutable ,而String是 immutable 。不可变意味着它不会改变,所以你对它没有被同步的观点毫无意义 - 没有可能的同步变化。
简而言之,如果您不需要StringBuilders额外功能(这在字符串中很常见),String会更有效率。它还在JVM中进行了高度优化的特殊处理,而Java中的其他对象则没有。
特定于字符串的优化(String池)的最值得注意的示例使得字符串的行为类似于常量,因为可以在整个应用程序中自动共享同一实例,从而节省内存和时间。对于其他对象,这不可能自动实现,对于可变对象,通常甚至不需要它。与自定义池相比,字符串池已显示为允许more objects with better performance。仅使用一个String实例来获得性能优势的过程称为string interning。
由于您只使用一个实例,因此在比较时,您只需要比较参考。对于每个StringBuilder实例,您需要评估对象的内容以执行此操作。 Stringbuilder uses an Array as a backing object和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