Is there an easy way to concatenate several lines of text into a string without constantly appending a newline?

32,306

Solution 1

You can use a StringWriter wrapped in a PrintWriter:

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

Solution 2

AFAIK there's no library class that allows you to do so.

The following does the work though:

class DesiredStringThinger {
  StringBuilder text = new StringBuilder();

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

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

Solution 3

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);
}

Solution 4

Here's a Java 8 solution using a stream:

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"));
    }

}

Solution 5

You can use from Apache Commons the StringUtils.join helper. Which allows to build a String from a list. You can add the 'delimiter' character/string.

Share:
32,306
Marshmellow1328
Author by

Marshmellow1328

Updated on February 01, 2021

Comments

  • Marshmellow1328
    Marshmellow1328 over 3 years

    So I essentially need to do this:

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

    There is more involved, but that's the basic idea. Is there anything out there that might let me do something more along the lines of this though?

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

    Obviously, it does not need to work exactly like that, but I think I get the basic point across. There is always the option of writing a loop which processes the text myself, but it would be nice if there is a standard Java class out there that already does something like this rather than me needing to carry a class around between applications just so I can do something so trivial.

    Thanks!

  • matt b
    matt b about 14 years
    I think Marshmellow1328 wants a new line between each token when append() is called
  • Tomislav Nakic-Alfirevic
    Tomislav Nakic-Alfirevic about 14 years
    While correct, this will cause performance problems with relatively small numbers of lines: Roman's solution is in that respect much better.
  • Yaneeve
    Yaneeve about 14 years
    Just a recommendation: use @Roman's 'String lsp = System.getProperty("line.separator");' but declare it as a private static member
  • Enno Shioji
    Enno Shioji about 14 years
    StringBuffer is synchronized, but I "performance problems"? Nah. Uncontended lock acquisition is fast. In fact, in later JVM, unnecessary locks are optimized away anyway. But I guess you don't have reason to prefer StringBuffer, either...
  • Steve McLeod
    Steve McLeod about 14 years
    This solution is elegant. I like the use of delegation to create a wrapper.
  • missingfaktor
    missingfaktor about 14 years
    @Zwei: Thanks. I'll change that to StringBuilder.
  • Steve McLeod
    Steve McLeod about 14 years
    @Tomislav: I don't see why performance should be particularly worse in this solution.
  • Tomislav Nakic-Alfirevic
    Tomislav Nakic-Alfirevic about 14 years
    There's a fairly good explanation e.g. here: javapractices.com/topic/TopicAction.do?Id=4 "Compilers often implement concatenation operations by creating intermediate objects in the background. Such intermediate objects are not needed by StringBuilder." I ran into this when trying to concatenate whole files (<30kb) and the difference in efficiency between the "+" operator and using a StringBuffer was extreme.
  • matt b
    matt b about 14 years
    @Tomislav the same article also says "then the difference in relative performance is very small, and possibly not even measurable (the great majority of use cases of the concatenation operator fall into this category)"
  • Tomislav Nakic-Alfirevic
    Tomislav Nakic-Alfirevic about 14 years
    @Matt: True, but I did specify in my 1st comment that I am in fact talking about a specific case. In retrospect, my wording was a bit unfortunate, but on my own project I saw performance problems when concatenating a couple of hundred lines of text, which is what I consider a "relatively small number of lines". Of course, it depends on how often you invoke such a routine (all of the time, in my case).
  • matt b
    matt b about 14 years
    @Tomislav I don't see a significant difference between this answer and Roman's, both make use of StringBuilder and append() under the covers. Neither use literal concatenation.
  • Tomislav Nakic-Alfirevic
    Tomislav Nakic-Alfirevic about 14 years
    I was convinced that Rahul's initial concatenation code was something along the lines of text += line;, but looking at the answer history, it seems I was mistaken. My apologies, Rahul.
  • missingfaktor
    missingfaktor about 14 years
    @Tomislav: You were right. First I had posted a quick and dirty text += line; solution and changed it to the StringBuffer alternative within another 2-3 minutes (before I saw your comment). Perhaps that's why the original post doesn't show up in edit history. Then I changed it to StringBuilder on Zwei's suggestion. My apologies for all the confusion that I caused. :(
  • Marshmellow1328
    Marshmellow1328 about 14 years
    This is actually where I started. Then I got tired of adding the newline character for every line. While I could have easily created a small helper function to do it, I was hoping there might be something that already exists out there rather than having to expand my basic java library.
  • Frederik
    Frederik about 3 years
    This is perhaps the cleanest solution based on the stl and with an output example. Works also if you use a dynamic ArrayList instead of the StringArray.