Java 连接字符串与静态字符串

Java concatenate strings vs static strings

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

例如

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 个,但这个数字可能会过剩很多)

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

您可以像这样在字符串中设置开头句

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

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

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

然后你可以做foreach循环,将数组中的每个元素与开头的句子连接起来。

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

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

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

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

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

StringJoiner myJoiner = new StringJoiner("/")

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

示例:

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]);
}

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

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

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