字符串连接,然后循环追加
String Concatenation and then append in a loop
从 Bruce Eckel 所著的 "Thinking in Java" 一书中找到了这段摘录。
If you try to take shortcuts and do something like append(a + ": " + c)
, the compiler will jump in and start making more StringBuilder
objects again.
这是否意味着我们不应该用一行代码替换一组追加操作;例如 result.append(i + ": " + 2*i + " ")
?
StringBuilder result = new StringBuilder();
for(int i = 0; i < 25; i++) {
result.append(i);
result.append(": ");
result.append(2*i);
result.append(", ")
}
上述说法是否也适用于 Java 8?
SO 上的 answer 摘录:(让我更加困惑)
At the point where you're concatenating in a loop - that's usually
when the compiler can't substitute StringBuilder by itself.
也欢迎与首选编码风格相关的任何方面。
这不是编译器会有效地为您执行的优化。从文体上来说,我会这样写。
StringBuilder result = new StringBuilder();
for (int i = 0; i < 25; i++) {
result.append(i).append(": ").append(2 * i).append(", ");
}
注意:IDE(如 IntelliJ)将检测并为此提供自动修复,因为它是一种常见的翻译。
是的,当性能至关重要时,我们仍然应该使用链式追加而不是字符串连接。
然而,当性能不是很重要时,我们应该努力提高代码的可读性、清晰度和重用性。因此我的风格选择是:
IntStream
.range(0, 25)
.map(i, String.format("%d: %d", i, i*2)
.collect(Collectors.joining(", "));
基本上,编译器用 StringBuilder
替换 String
连接的实例,所以你的行
result.append(i + ": " + 2*i + " ");
改为
result.append(new StringBuilder().append(i).append(": ").append(2*i).append(" ").toString());
如您所见,它只是创建了 另一个 StringBuilder
,这是多余的,因为您已经有了一个。最重要的是,它需要在循环的 每次 迭代中这样做,导致大量创建和垃圾收集无用。
所以是的,直接附加到您已经拥有的 StringBuilder
肯定会更好,而不是连接。是否以单行流利的方式执行此操作主要是个人喜好问题。
我不确定您找到的 "can't substitute StringBuilder
" 答案是什么意思。他们可能意味着它不会重复使用您现有的构建器(而是创建一个新的构建器)。
这对 Java 8 仍然有效,尽管从那以后有其他流媒体方法,就像其他答案之一显示的那样。
从 Bruce Eckel 所著的 "Thinking in Java" 一书中找到了这段摘录。
If you try to take shortcuts and do something like
append(a + ": " + c)
, the compiler will jump in and start making more StringBuilder objects again.
这是否意味着我们不应该用一行代码替换一组追加操作;例如 result.append(i + ": " + 2*i + " ")
?
StringBuilder result = new StringBuilder();
for(int i = 0; i < 25; i++) {
result.append(i);
result.append(": ");
result.append(2*i);
result.append(", ")
}
上述说法是否也适用于 Java 8?
SO 上的 answer 摘录:(让我更加困惑)
At the point where you're concatenating in a loop - that's usually when the compiler can't substitute StringBuilder by itself.
也欢迎与首选编码风格相关的任何方面。
这不是编译器会有效地为您执行的优化。从文体上来说,我会这样写。
StringBuilder result = new StringBuilder();
for (int i = 0; i < 25; i++) {
result.append(i).append(": ").append(2 * i).append(", ");
}
注意:IDE(如 IntelliJ)将检测并为此提供自动修复,因为它是一种常见的翻译。
是的,当性能至关重要时,我们仍然应该使用链式追加而不是字符串连接。
然而,当性能不是很重要时,我们应该努力提高代码的可读性、清晰度和重用性。因此我的风格选择是:
IntStream
.range(0, 25)
.map(i, String.format("%d: %d", i, i*2)
.collect(Collectors.joining(", "));
基本上,编译器用 StringBuilder
替换 String
连接的实例,所以你的行
result.append(i + ": " + 2*i + " ");
改为
result.append(new StringBuilder().append(i).append(": ").append(2*i).append(" ").toString());
如您所见,它只是创建了 另一个 StringBuilder
,这是多余的,因为您已经有了一个。最重要的是,它需要在循环的 每次 迭代中这样做,导致大量创建和垃圾收集无用。
所以是的,直接附加到您已经拥有的 StringBuilder
肯定会更好,而不是连接。是否以单行流利的方式执行此操作主要是个人喜好问题。
我不确定您找到的 "can't substitute StringBuilder
" 答案是什么意思。他们可能意味着它不会重复使用您现有的构建器(而是创建一个新的构建器)。
这对 Java 8 仍然有效,尽管从那以后有其他流媒体方法,就像其他答案之一显示的那样。