简体   繁体   English

字符串串联,然后附加到循环中

[英]String Concatenation and then append in a loop

Found this excerpt from the book "Thinking in Java" written by Bruce Eckel. 从布鲁斯·埃克尔(Bruce Eckel)撰写的“ 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. 如果尝试使用快捷方式并执行诸如append(a + ": " + c) ,则编译器将跳入并再次开始制作更多 StringBuilder对象。

Does that mean that we shouldn't replace a group of append operations with a single line of code; 这是否意味着我们不应该用单行代码替换一组追加操作; eg result.append(i + ": " + 2*i + " ") ? 例如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(", ") 
}

Does the above statement hold true for Java 8 as well? 上述声明对Java 8也适用吗?

Excerpt from this answer on SO: (confused me even more) 摘自SO的这个答案 :(让我更加困惑)

At the point where you're concatenating in a loop - that's usually when the compiler can't substitute StringBuilder by itself. 循环中进行连接的那一刻-通常是编译器无法单独替代 StringBuilder时。

Any aspect related to preferred coding style is also welcome. 也欢迎与首选编码样式有关的任何方面。

This is not an optimisation the compiler will do for you efficiently. 这不是编译器将为您高效完成的优化。 Stylistically, I would write it like this. 从风格上讲,我会这样写。

StringBuilder result = new StringBuilder();
for (int i = 0; i < 25; i++) {
    result.append(i).append(": ").append(2 * i).append(", ");
}

NOTE: IDEs, like IntelliJ, will detect and provide an auto-fix for this as it's a common translation. 注意:IDE(如IntelliJ)将检测并为此提供自动修复,因为它是常见的翻译。

Basically, the compiler replaces instances of String concatenation with StringBuilder s, so your line 基本上,编译器将String连接实例替换为StringBuilder ,因此您的代码行

result.append(i + ": " + 2*i + " ");

Is changed to 改为

result.append(new StringBuilder().append(i).append(": ").append(2*i).append(" ").toString());

Like you can see, it just creates another StringBuilder , which is redundant since you already have one. 如您所见,它只是创建了另一个 StringBuilder ,因为您已经有一个,所以它是多余的。 On top of that, it needs to do so in every iteration of the loop, causing a lot of creation and garbage collection for nothing. 最重要的是,它需要在循环的每个迭代中执行此操作,从而导致大量的创建和垃圾回收。

So yes, it would definitely be better to just append to the StringBuilder you already have directly, instead of concatenating. 因此,是的,最好直接附加到您已经拥有的StringBuilder ,而不是进行串联。 Whether or not you do this in a single fluent line is mostly a matter of preference. 是否在单个流水线中执行此操作通常是一个优先事项。

I'm not sure what the answer you found means by "can't substitute StringBuilder ". 我不确定通过“不能替代StringBuilder ”找到的答案意味着什么。 They probably meant that it won't re-use your existing builder (and instead create a new one). 他们可能意味着它不会再使用您现有的构建器(而是创建一个新的构建器)。

This is still valid for Java 8, although since then there are alternative streaming methods, like one of the other answers shows. 这对于Java 8仍然有效,尽管从那时起,还有其他流方法,就像其他答案之一所示。

Yes, we should still use chained appends instead of string concatenation when performance is crucial. 是的,当性能至关重要时,我们仍应使用链式追加而不是字符串连接。

However, whenever performance is not crucial, we should strive for code readability, clarity and reuse. 但是,每当性能不是很关键时,我们都应努力提高代码的可读性,清晰度和重用性。 Thus my stylistic choice would be: 因此,我的风格选择是:

IntStream
    .range(0, 25)
    .map(i, String.format("%d: %d", i, i*2)
    .collect(Collectors.joining(", "));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM