Java中StringBuilder的字符串优势

时间:2016-12-19 09:19:21

标签: java string

为什么有人会./testConcat line pdb8mhtA pdbfile pdb8mhtA.pdb 使用String

我知道以下事实:

  • StringBuilder优于String,
  • 字符串是不可变的,
  • 我们可以使用StringBuilder完成所有内容以及String的功能。
  • 并且也不能说String更快,因为两者都不同步。

那么,如果StringBuilder已经存在,为什么有人会使用String

1 个答案:

答案 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