优雅地删除 StringBuilder 中最后一个字符串后的 "\n" 分隔符。

21

有以下 Java 代码,它使用 "\n"(即回车符)作为定界符创建了一个 StringBuilder:

while (scanner.hasNextLine()){
    sb.append(scanner.nextLine()).append("\n");
}

遇到了一个问题,最后一行字符串(line)有 "\n" 符号。

如何优雅地从结果中删除最后的 "\n" 字符?

谢谢。

7个回答

26

这对我一直有效

sb.setLength(sb.length() - 1);

这个操作非常轻量级,内部的值只会减少1,表示当前内容的大小。

如果你认为缓冲区可能为空,请在执行此操作之前检查长度值。


1
这种方法很有趣,尽管后面的长度检查似乎是一个缺点。 - cherouvim
@cherouvim 是的。另一方面,你不会分配不必要的内存,就像使用“trim”或“join”一样。虽然,你的答案也很好,我经常自己使用那种方法。 - Nikita Rybak
在需要添加数百万个元素的极高性能情况下,我肯定会使用您的方法,因为它具有最快的循环(无if检查)。 - cherouvim
长度调用可能会在运行时被直接变量查找所取代...并且仅在检查长度==0之后发生一次,不像其他解决方案,在循环的每次迭代中都要进行if检查。因此与其他方法相比没有真正的缺点。 - TofuBeer
在Windows中,这只会删除0A字符,但是你仍然会在末尾有0D。 - GML-VS
为了使程序更加“健壮”,您可以使用System.Environment.NewLine.Length来删除系统的换行字符串。 - Ryan Gregg

13
如果你正在处理行数较少的文本,可以将所有行放入一个List<String>中,然后使用StringUtils.join(myList, "\n");来连接它们。
另一个选择是对生成的字符串进行trim()操作。
在发现 guava 的不错的Joiner类之后更新: Joiner.on('\n').join(myList)

+1比我的更好,假设可以合理地知道/存储List<String> - andersoj
StringUtils(即sringframework类)中找不到join方法。 - sergionni
抱歉我表达不太清楚,我是在指apache commons-lang库。我已将链接放在答案中。 - oksayt
好的,现在我明白了,这是Apache库,不幸的是我们的项目中没有。 - sergionni

4

您可以在不换行的情况下构建结果来消除:

String separator = "";
while (scanner.hasNextLine()){
    sb.append(separator).append(scanner.nextLine());
    separator = "\n";
}

3

你可以选择从未添加它,而不是必须将其移除。

while (scanner.hasNextLine()) {
    if (sb.length()>0) sb.append("\n");
    sb.append(scanner.nextLine());
}

如果开头的一行或多行为空,则这无法正常工作。 - Nayuki

3

sb.deleteCharAt(sb.length()-1);


2
bool isFirst = true;
while (scanner.hasNextLine()){
  if(!isFirst)
    sb.append("\n"));
  else
    isFirst = false;

  sb.append(scanner.nextLine());

}

1
优雅的消除 else isFirst = false; 的方法:if (!isFirst | (isFirst = false)) - aioobe

1
if (scanner.hasNextLine()) 
  sb.append(scanner.nextLine());
while (scanner.hasNextLine()){
  sb.append("\n").append(scanner.nextLine());
}

这里的问题是追加时有代码重复。 在这个例子中很简单,但在其他情况下可能不是。 因此复制不是好的选择。 - cherouvim
同意。我认为trim()解决方案不够优雅,而我的解决方案存在代码重复的问题。也许join()是最好的选择... - andersoj

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