每种不同方式的优点/缺点是什么。我认为 StringBuilder 会更有效率,因为每次更新索引时转换为 char 数组都会生成数组的副本。
如所写,第二个示例中的代码将仅创建两个数组:一个在您调用时创建toCharArray()
,另一个在您调用时创建String.valueOf()
(String
将数据存储在 char[] 数组中)。您正在执行的元素操作不应触发任何对象分配。当您读取或写入元素时,不会对数组进行复制。
如果您要进行任何类型的String
操作,推荐的做法是使用StringBuilder
. 如果您正在编写对性能非常敏感的代码,并且您的转换不会改变字符串的长度,那么直接操作数组可能是值得的。但是由于您正在学习 Java 作为一门新语言,我猜您不是在高频交易或任何其他延迟至关重要的环境中工作。因此,您最好使用StringBuilder
.
如果您正在执行任何可能产生与原始字符串长度不同的字符串的转换,您几乎肯定应该使用StringBuilder
; 它将根据需要调整其内部缓冲区的大小。
在相关的说明中,如果您正在执行简单的字符串连接(例如,s = "a" + someObject + "c"
),编译器实际上会将这些操作转换为一系列StringBuilder.append()
调用,因此您可以自由使用任何您认为更美观的方法。我个人更喜欢+
运营商。但是,如果您要跨多个语句构建字符串,则应该创建一个StringBuilder
.
例如:
public String toString() {
return "{field1 =" + this.field1 +
", field2 =" + this.field2 +
...
", field50 =" + this.field50 + "}";
}
在这里,我们有一个包含许多串联的单一长表达式。您无需担心手动优化它,因为编译器将使用单个并重复StringBuilder
调用它。append()
String s = ...;
if (someCondition) {
s += someValue;
}
s += additionalValue;
return s;
在这里,您最终会在StringBuilders
幕后创建两个,但除非这是延迟关键应用程序中非常热的代码路径,否则真的不值得担心。给定类似的代码,但有更多单独的连接,可能值得优化。如果您知道字符串可能非常大,也是如此。但不要只是猜测——测量!在尝试修复之前证明存在性能问题。 (注意:这只是“微优化”的一般规则;显式使用 a 很少有缺点StringBuilder
。但不要认为它会产生可衡量的差异:如果你担心它,你应该实际测量。)
String s = "";
for (final Object item : items) {
s += item + "\n";
}
在这里,我们对每个循环迭代执行单独的连接操作,这意味着每次循环StringBuilder
都会分配一个新的。在这种情况下,可能值得使用单个StringBuilder
,因为您可能不知道集合有多大。我会认为这是“在优化规则之前证明存在性能问题”的一个例外:如果操作有可能根据输入的复杂性爆炸,请谨慎行事。