【问题标题】:Gracefully remove "\n" delimiter after last String within StringBuilder在 StringBuilder 中的最后一个字符串之后优雅地删除“\n”分隔符
【发布时间】:2011-04-26 08:48:45
【问题描述】:

有以下 Java 代码,用“\n”创建StringBuilder,即回车分隔符:

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

发生了,在最后一个字符串(行)之后有“\n”符号。

如何优雅地从生成的StringBuilder 对象中删除最后一个“\n”?

谢谢。

【问题讨论】:

    标签: java string newline stringbuilder


    【解决方案1】:

    这对我一直有效

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

    操作非常轻量级,保持当前内容大小的内部值只会减少 1。

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

    【讨论】:

    • 这种方法很有趣,虽然后面的长度检查似乎有缺点。
    • @cherouvim 是的。另一方面,您不会分配不必要的内存,例如使用“trim”或“join”。虽然,你的回答也不错,但我自己也经常使用这种方法。
    • 在性能极高的情况下,我必须在 sb 上添加数百万个元素,我肯定会使用您的方法,因为它具有最快的循环(没有 if 检查)。
    • 长度调用可能会在运行时被直接变量查找替换......并且长度 == 0 的检查只发生一次,这与其他解决方案不同,其中 if 的每次迭代都完成环形。因此,与其他方式相比,没有真正的缺点。
    • 在 Windows 中这只会删除 0A 字符,但最后仍然有 0D
    【解决方案2】:

    如果您使用的行数足够少,您可以将所有行放在List<String> 中,然后使用StringUtils.join(myList, "\n");

    另一个选项是trim() 得到的字符串。

    发现guava的整洁Joiner类后更新:

    Joiner.on('\n').join(myList)

    【讨论】:

    • +1 比我的好,假设 List<String> 可以被合理地知道/存储。
    • 其实找不到StringUtils的join方法(即sringframework类)
    • 抱歉不清楚,我指的是 apache commons-lang 库。我把链接放在答案中。
    • 好的,现在我明白了,它的 apache 库,不幸的是我们的项目中没有
    【解决方案3】:

    您可以在没有换行符的情况下构建结果以摆脱:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        您可以永远不要添加它,而不必删除它。

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

        【讨论】:

        • 如果开头的一行或多行为空白,则无法正常工作。
        【解决方案6】:
        bool isFirst = true;
        while (scanner.hasNextLine()){
          if(!isFirst)
            sb.append("\n"));
          else
            isFirst = false;
        
          sb.append(scanner.nextLine());
        
        }
        

        【讨论】:

        • 摆脱else isFirst = false;的巧妙方法:if (!isFirst | (isFirst = false))
        【解决方案7】:
        if (scanner.hasNextLine()) 
          sb.append(scanner.nextLine());
        while (scanner.hasNextLine()){
          sb.append("\n").append(scanner.nextLine());
        }
        

        【讨论】:

        • 这里的问题是追加的代码重复。在这个例子中它是微不足道的,但在其他情况下它可能不是。所以复制不好。
        • 同意。我认为trim() 解决方案不优雅,而且我的解决方案存在代码重复问题。也许join() 是最好的……
        猜你喜欢
        • 2011-03-24
        • 1970-01-01
        • 2016-05-27
        • 1970-01-01
        • 2016-03-13
        • 1970-01-01
        • 2020-03-12
        • 2017-03-26
        • 2014-11-08
        相关资源
        最近更新 更多