【问题标题】:Using + to concat string in Java在 Java 中使用 + 连接字符串
【发布时间】:2013-04-19 15:32:57
【问题描述】:

我有一个巨大的字符串如下:

String str = "aaaaaaa" 
        + "bbbbbbbb" 
        + "cccccccc" 
    .... 

        + "zzzzzzzz";  // about 200 lines long

是不是很浪费内存?放在一行还是用StringBuilder会更好吗? 这样做是为了创建一个长 sql。

【问题讨论】:

  • 一个更好的问题是,你为什么要连接那么多行?
  • @Makoto 你还会怎么做?
  • 由于您使用它来构建 SQL 查询,我会寻找更简洁的 API 来创建它,例如 Criteria API

标签: java string concatenation


【解决方案1】:

没有。如果您的所有字符串都是恒定的(因为它们在您的问题中),编译器将在编译时执行连接。所以最终的性能StringBuilder 版本更好

否则它将使用StringBuilder(或StringBuffer)执行任何非常量部分的连接。

所以编译后的版本:

String x = "a" + "b";

应该完全与:

String x = "ab";

请注意,“非常量”部分可能意味着您有时可以明智地使用括号来获得(非常微小的)额外效率。例如:

int value = ...;
String x = "a" + value + "b" + "c";

... 效率低于:

int value = ...;
String x = "a" + value + ("b" + "c");

... 作为第一个附加 "b""c" 分别。高效版相当于O:

int value = ...;
String x = "a" + value + "bc";

我不记得曾经看到这被用作合法的微优化,但它至少是一个兴趣点。

【讨论】:

  • 编译器不/不应该为你做那个微优化吗?或者,从另一个角度来看,foo 的任何值是否可能与(foo + "a") + "b"foo + "ab" 不同?
  • @IlmariKaronen:不是我能想到的——但这就是我在标准 javac 中观察到的。我认为这将是一个有效的优化。
  • 有没有办法不进行优化?
【解决方案2】:

在当前版本的 Java 中,每个 +(连接)操作都会自动编译为 StringBuilder append() 操作。但是,如果它在一个循环中,它将为每次迭代创建一个新的 StringBuilder,从而抵消它的影响 - 所以你最好明确地管理 StringBuilder

【讨论】:

    【解决方案3】:

    没有。编译器会为你优化成StringBuilder

    编辑:正如 Louis Wasserman 所指出的,它还会为您组合字符串文字,因此上面的语句在编译时只是一个字符串。

    【讨论】:

    • 不太正确。如果所有这些都是文字字符串,编译器只会将其优化为单个String,而根本不使用StringBuilder
    【解决方案4】:

    AFAIK JVM 内部有一个字符串池,您创建的每个字符串都存储在那里,丢弃最旧/最少使用的字符串(我不确定它如何选择哪些字符串)。如果你明确地调用 String.intern() 你是在告诉 JVM 将字符串放入池中。

    当您使用 + 连接两个字符串时,您最终会在池中得到三个字符串。 如果你连接 a + b + c,你会得到 5 个字符串 (a, b, ab, c, abc)

    至少我记得在旧 JVM 版本上是这样,但 Luiggi 很可能是对的,在新版本上它的内部优化

    【讨论】:

      【解决方案5】:

      代码:

      String str = "aaaaaaa" + "bbbbbbbb" + "cccccccc";
      

      在编译时转换为:

      String str = (new StringBuilder()).append("aaaaaaa").append("bbbbbbbb").append("cccccccc").toString();
      

      因此,使用 StringBuilder 似乎没有任何区别。

      有一篇非常好的文章,将 concat (+) 与 StringBuilder 和 StringBuffer 的性能进行了密切比较,并附有折线图:

      StringBuilder vs StringBuffer vs String.concat - Done Right.

      【讨论】:

        猜你喜欢
        • 2011-04-02
        • 2012-08-28
        • 1970-01-01
        • 2016-06-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多