有没有一种简单的方法将几行文本连接成一个字符串,而不需要不断地添加新行?

16

所以我基本上需要做这个:

String text = "line1\n";
text += "line2\n";
text += "line3\n";
useString( text );

这还涉及到更多细节,但那就是基本思路。不过,是否有什么工具可以让我更多地按照这个思路进行操作呢?

DesiredStringThinger text = new DesiredStringThinger();
text.append( "line1" );
text.append( "line2" );
text.append( "line3" );
useString( text.toString() );

显然,它不必完全按照那样工作,但我认为我已经传达了基本观点。总是有一个选项,即编写一个循环来处理文本,但如果有一个标准的Java类已经做了类似这样的事情,而我不需要在应用程序之间携带类来执行如此琐碎的任务,那就太好了。

谢谢!

11个回答

17

您可以使用一个被包装在 PrintWriter 中的 StringWriter

StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter, true);
writer.println("line1");
writer.println("line2");
writer.println("line3");
useString(stringWriter.toString());

8
据我所知,目前没有任何库可以让您这样做。但是以下方法可以解决问题:
class DesiredStringThinger {
  StringBuilder text = new StringBuilder();

  public void append(String s) { text.append(s).append("\n"); }

  @Override
  public String toString() { return text.toString(); }
}

1
StringBuffer是同步的,但我会有“性能问题”吗?不会。无竞争锁获取速度很快。实际上,在后期JVM中,不必要的锁已经被优化掉了。但我猜你也没有理由偏爱StringBuffer... - Enno Shioji
1
这个解决方案非常优雅。我喜欢使用委托来创建包装器的方式。 - Steve McLeod
1
@Tomislav:我不明白为什么这种解决方案的性能应该特别差。 - Steve McLeod
1
我曾经确信Rahul的初始连接代码大致为text +=line;,但查看答案历史记录后,发现我错了。对不起,Rahul。 - Tomislav Nakic-Alfirevic
1
@Tomislav:你是对的。一开始我发布了一个快速而简单的text += line;解决方案,但在2-3分钟内就改为了StringBuffer替代方案(在看到你的评论之前)。也许这就是为什么原始帖子没有出现在编辑历史记录中的原因。然后我根据Zwei的建议将其更改为StringBuilder。对我造成的所有混乱表示歉意。:( - missingfaktor
显示剩余7条评论

5

Java SE 8

在Java SE 8中,可以通过以下两种方式进行:

  1. 使用String#join
  2. 使用Stream

示例:

import java.util.Arrays;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        String[] arr = { "line1", "line2", "line3" };

        // Using String#join
        System.out.println(String.join(System.lineSeparator(), arr));

        System.out.println();

        // Using Stream
        System.out.println(Arrays.stream(arr).collect(Collectors.joining(System.lineSeparator())));
    }
}

输出:

line1
line2
line3

line1
line2
line3

1
这可能是基于STL的最干净的解决方案,并附有输出示例。 如果您使用动态ArrayList而不是StringArray,也可以工作。 - Frederik

4
public String createString () {
   StringBuilder sb = new StringBuilder ();
   String txt = appendLine("firstline", sb).appendLine("2ndLine", sb).toString();
}

private StringBuilder appendLine (String line, StringBuilder sb) {
   String lsp = System.getProperty("line.separator");
   return sb.append (line).append (lsp);
}

3

以下是使用流实现的Java 8解决方案:

public class DesiredStringThinger {

    private List<String> items = new ArrayList<>();

    public void append(String s) {
        items.add(s);
    }

    @Override
    public String toString() {
        return items.stream().collect(Collectors.joining("\n", "", "\n"));
    }

}

2
如果您愿意使用外部库,请查看 Guava 中的 Joiner
您的代码将变成类似于以下内容。
String result = Joiner.on("\n").join(parts);

其中parts是一个Iterable<String>


2
您可以使用来自Apache Commons的StringUtils.join助手。它允许从列表中构建一个字符串。您可以添加“分隔符”字符/字符串。

1
你可以使用 StringBuffer。
StringBuffer text = new StringBuffer();
text.append("line1");  
text.append("line2");  
...  
useString(text.toString());   

这不会添加新行字符,但您当然也可以为每行附加它。


1
我认为Marshmellow1328希望在调用append()时每个标记之间有一个新行。 - matt b
这实际上是我开始的地方。然后,我厌倦了为每一行添加换行符。虽然我可以轻松创建一个小助手函数来完成它,但我希望能够找到已经存在的东西,而不是扩展我的基本Java库。 - Marshmellow1328

0
或许最低影响的方法是添加一个静态方法,用于在StringBuilder中添加新行。
 public static StringBuilder appendln(StringBuilder buff, String str) {
     return buff.append(str).append('\n');
 }

但是@Joachim Sauer比我更早使用了我首选的解决方案。对于更复杂的示例,您可能希望使用自己的Writer修饰符,如@Rahul G(仅使用私有字段)。

0

如果你不是特别在意性能,我认为这个代码干净整洁。

class DesiredStringThinger {
  StringBuilder sb = new StringBuilder();

  public void concat(String... s) { 
      for(String str : s){
         sb.append(s).append("\n");
      }
  }

  @Override
  public String toString() { 
      return sb.toString();
  }
}

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