字符串变量拼接

3

我有以下几行代码。我的问题是应该选择哪个?

public static String convertMapToString ( Map < String, String > map )
{
    StringBuilder str = new StringBuilder ( 200 ) ;
    for ( Entry < String, String > entry : map.entrySet ( ) )
    {
        str.append ( entry.getKey() + " = " + entry.getValue() ) ; 
    }
    return str.toString()  ;
}

我应该选择以下方式,因为我怀疑在每次迭代中,上面的append语句可能会由于+操作而创建两个额外的字符串。
public static String convertMapToString ( Map < String, String > map )
{
    StringBuilder str = new StringBuilder ( 200 ) ;
    for ( Entry < String, String > entry : map.entrySet ( ) )
    {
        str.append (entry.getKey());
        str.append (" = ");
        str.append (entry.getValue()) ; 
    }
    return str.toString()  ;
}

4
反编译两个版本并查看编译器对它们所做的操作。 - Tom
2
第二个代码片段可能会生成比第一个更少的字符串对象,所以我更喜欢它。 - Eran
@Tom 同意,我猜选项2是“更好”的,因为需要连接字符串,而StringBuilder将不得不循环相同数量的char。因此,选项1似乎与选项2相同,但多了一个不必要的连接。 - Maljam
@Tom,我在两个版本的反编译代码中没有发现任何变化,除了将键和值部分转换为字符串。你是指这个问题吗?还是你还有其他想让我意识到的问题? - SacJn
那么编译后的代码对于两个版本来说是相等的,所以你选择哪个并不重要。但是请注意,第一个版本没有编译成 str.append(new StringBuilder(entry.getKey()).append(" = ").append(entry.getValue()).toString()); - Tom
我的意思是反编译的代码在两个版本中与原始代码完全相同。 - SacJn
3个回答

3

按照传统智慧,为了最佳 Strings 拼接效果,您应该选择 StringBuilder.append 方法,这在您的示例中将是选项 2。

请注意,根据语言规范,即使您使用 "+" 进行拼接,实现也可能会选择将其优化为 StringBuilder.append,但这并不保证,因此如果优化执行是您的首要任务,我建议始终选择选项 2。


感谢提供规范链接。 - SacJn

1
为了可读性:第一个。
为了性能:第二个。
第二段代码应该生成更少的对象,因此更快,使用的内存也更少。(尽管编译器会尝试优化代码以使用StringBuilder,但正如@Jas所说的那样:这并不保证)
现在,知道了这一点,使用你需要的任何东西或者你认为最适合你的东西。
我通常只在循环中使用StringBuilder,在它们之外使用字符串添加。

1
但是使用的内存和所有内容:这只是你认为可能是这样的猜测,还是你实际上比较了编译结果? - Tom
2
你是对的,@Tom,我已经编辑了回复。它应该具有相同的性能和相同的编译代码,但不能保证。因此,如果您想确保使用StringBuilders,您应该自己将它们放入您的代码中或反编译您编译的所有代码以进行检查(显然,如果您更改编译器,则需要重新检查)。因此,我在循环和简单函数中使用StringBuilders,并在它们之外进行字符串添加。 - inigoD

0

推荐使用版本二,因为版本一会创建大量不必要的对象,性能明显较慢。

字符串拼接被编译成创建一个新的 StringBuilder,对每个部分调用 append 方法,然后调用 toString。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接