【问题标题】:Java concatenate strings vs static stringsJava 连接字符串与静态字符串
【发布时间】:2016-01-07 16:33:25
【问题描述】:

我试图更好地理解字符串。我基本上是在制作一个需要很多字符串的程序。但是,很多字符串非常非常相似,只是在字符串末尾需要一个不同的单词。

例如

String one = "I went to the store and bought milk"
String two = "I went to the store and bought eggs"
String three = "I went to the store and bought cheese"

所以我的问题是,在处理字符串时最适合采用什么方法?将 2 个字符串连接在一起是否比仅使用静态字符串有任何好处,例如性能或内存管理?

例如

String one = "I went to the store and bought "
String two = "milk" 
String three = "cheese"
String four = one + two
String five = one + three

我只是想找出处理所有这些字符串的最佳方式。 (如果放置我正在使用的一些字符串有帮助,我目前有 50 个,但数量可能会过剩)

【问题讨论】:

  • 可读性更重要。我认为两者之间没有真正的性能差异
  • static final Strings, well explained here Strings 对于常量部分是个好主意。
  • 使用文字字符串进行本地化有时比生成的字符串更容易。
  • 你能定义“巨大”和“很多”吗?因为您给出的唯一数字(50)与计算机的“很多”相差甚远。 50 个 40 个字符的字符串构成 4KB 的内存。你想达到什么目的?所有这些硬编码的字符串是干什么用的?在我看来,这就像一个 X/Y 问题。
  • 代码应该可读但也可维护。如果字符串在多个地方使用或可能会更改,则将它们放入变量中可能是更合适的选择。无论哪种方式,问题主要是基于意见的,并且实际上取决于开发人员来判断采取哪个选项。

标签: java string string-concatenation


【解决方案1】:

正如 spooky 所说,代码的主要关注点是可读性。除非您正在为手机开发程序,否则您不需要管理您的资源。话虽如此,您是创建大量独立的Strings 还是将基础String 与变化的小块连接起来并不重要。无论哪种方式,您都不会真正注意到更好的性能。

【讨论】:

  • 没有评论权限。这是我谈论这个问题的唯一方式。
  • 我知道..这就是我没有投反对票的原因..我们都从那里开始..所以我们将不得不接受它。
【解决方案2】:

你可以把开头的句子设置成这样的字符串

String openingSentence = "I went to the store and bought";

并通过定义一个字符串数组来单独定义每个单词,如下所示::

String[] thingsToBeBought = { "milk", "water", "cheese" .... };

然后您可以执行 foreach 循环并将数组中的每个元素与开头的句子连接起来。

【讨论】:

  • 宁可将openingSentence 设为静态最终字符串
【解决方案3】:

在 Java 中,如果您连接两个字符串(例如使用“+”),则会创建一个新字符串,因此需要对旧内存进行垃圾回收。如果要连接字符串,正确的做法是使用 StringBuilder 或 StringBuffer。

鉴于您对这些字符串确实是 URL 的评论,您可能希望拥有一个作为 URL 基础的 StringBuilder/StringBuffer,然后根据需要附加后缀。

【讨论】:

  • 感谢您的回复。但是,我不一定要采用串联的方法。当涉及到这样的字符串时,我只是要求一种好的方法。连接是否比静态字符串更优化。
  • @Awesomasaurus 来回答这个问题,从性能的角度来看,串联实际上并不是最优的。如上所述,它会创建多个字符串,然后 Java 需要对其进行垃圾收集。
【解决方案4】:

性能明智的最终静态字符串总是更好,因为它们是在编译时生成的。像这样的

final static String s = "static string";

如另一个示例所示的非静态字符串和串联的字符串是在运行时生成的。因此,即使性能对这么小的事情几乎没有影响,第二个示例在性能方面不如您的代码中的第一个示例:

// not as good performance wise since they are generated at runtime
String four = one + two
String five = one + three

【讨论】:

  • static final 使字符串成为编译时间常数。 final 关键字很重要:)
  • @VinodMadyalkar 是的。添加了一个小例子。感谢您指出:)
【解决方案5】:

由于您将使用此字符串作为 URL,因此我建议您使用 StringJoiner(如果您使用的是 JAVA 8)。它将和 StringBuilder 一样高效(不会每次执行连接时都创建一个新字符串),并且会在字符串之间自动添加“/”。

StringJoiner myJoiner = new StringJoiner("/")

【讨论】:

    【解决方案6】:

    在性能上不会有明显的差异,因此您执行此操作的方式更多的是偏好问题。我可能会将句子的第一部分声明为字符串并将单个购买项目存储在一个数组中。

    例子:

    String action = "I went to the store and bought ";
    String [] items = {"milk", "eggs", "cheese"};
    
    for (int x = 0; x< items.length; x++){
         System.out.println(action + items[x]);
    }
    

    【讨论】:

      【解决方案7】:

      在您给出的示例中,无论您声明每个可能的字符串还是单独的字符串都不会对内存或性能产生任何可衡量的影响。在声明大量字符串字面量的极端情况下,如果您声明每个可能的字符串,Java 的原生哈希表interned Strings 将使用更多内存,因为该表的缓存值会更长。

      如果您使用+ 运算符连接超过 2 个字符串,您将创建额外的字符串对象以进行 GC。例如,如果您有字符串a = "1"b = "2",并执行String s = "s" + a + b;,Java 将首先创建字符串“s1”,然后将其连接起来形成第二个字符串“s12”。使用StringBuilder 之类的东西来避免中间字符串。 (这不适用于编译时声明,但适用于运行时连接。)

      如果您恰好格式化字符串而不是简单地连接,请使用MessageFormatString.format()。它更漂亮,并且避免了使用 + 运算符时创建的中间字符串。类似于String urlBase = "http://host/res?a=%s&amp;b=%s"; String url = String.format(urlBase, a, b);,其中ab 是查询参数字符串值。

      【讨论】:

        猜你喜欢
        • 2014-11-21
        • 1970-01-01
        • 2016-07-19
        • 1970-01-01
        • 2011-04-02
        • 2012-07-19
        • 2011-12-06
        • 2011-06-01
        • 2013-05-22
        相关资源
        最近更新 更多