StringBuilder append content to a new line every time
Asked Answered
A

8

6

I am building a validation routine that validates contents and then gives warning (for failures) in form of StringBuilder. Say in below code I am checking lower bound for values paramX and paramY.

 StringBuilder sb= new StringBuilder();

        if(paramX<10){
            sb.append("paramX cannot be less than 10 ");
        }

        if(paramY<20){
            sb.append("paramY cannot be less than 20 ");
        }

        System.out.println(sb);

It gives output as: paramX cannot be less than 10 paramY cannot be less than 20

but i want output such that, each appended String will be printed on new line. Like below.

paramX cannot be less than 10 

paramY cannot be less than 20

I used following workarounds, but ended up repeating same code again and again(Which i don't want to).

sb.append(System.getProperty("line.separator")); // Add Explicit line separator each time
sb.append("\n");
sb.append("paramX cannot be less than 10 \n");

Is there a simpler way to do it?

Athenian answered 6/11, 2013 at 13:31 Comment(8)
Can you not just put the \n at at the end of the original append?Plumbo
sb.append("xxxx\n"); - why not this?Belisle
have you tried adding \n to your first append. sb.append("paramX cannot be less than 10 \n");Wart
@vlcekmi3 , Matt Penna: as posted above, i want to avoid manual padding / formatting.Athenian
then you can extend SB and add corresponding method e.g. appendLine()Belisle
@vlcekmi3 : as per my knowlwdge StringBuffer is final class. You can't extend it. Please refer to this url docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.htmlAthenian
@DarkKnight actually you can..Belisle
@vlcekmi3 This is just like writing your custom method with own formatting. which i want to avoid. And by the way it's not extending StringBuilder.Athenian
A
6

Just thought of sharing the new feature of jdk 8 i used for achieving same result. Using StringJoiner we can construct a sequence of characters separated by a delimiter.

StringJoiner formattedString= new StringJoiner("\n"); 
formattedString.add("XXX");
formattedString.add("YYY");
System.out.println(formattedString);  
Athenian answered 30/7, 2018 at 10:28 Comment(0)
L
7

If you don't want to do it over and over then write a helper method:

public void appendString(StringBuilder builder, String value) {
    builder.append(value + System.lineSeparator());
}

Then call:

if(paramX<10){
    appendString(sb, "paramX cannot be less than 10 ");
}

This way you only have a single place to maintain if you need to change the output format for the errors.

Leandra answered 6/11, 2013 at 13:36 Comment(2)
System.lineSeparator()Addicted
This builder.append(line); builder.append(lineSeparator); is more efficient then builder.append(line + lineSeparator); since the former creates a new String object for every line.Knuckle
A
6

Just thought of sharing the new feature of jdk 8 i used for achieving same result. Using StringJoiner we can construct a sequence of characters separated by a delimiter.

StringJoiner formattedString= new StringJoiner("\n"); 
formattedString.add("XXX");
formattedString.add("YYY");
System.out.println(formattedString);  
Athenian answered 30/7, 2018 at 10:28 Comment(0)
S
5

Another option is to use Apache Commons StrBuilder, which has the functionality that you're looking for.

StrBuilder.appendLn()

Shwalb answered 3/12, 2015 at 18:1 Comment(2)
It's deprecated now. Its documentation recommends to use org.apache.commons.text.StrBuilder instead.Cay
Hmmm, you sure? Doesn't appear to be deprecated. Either way, same functionality.Shwalb
N
4

The simple way would be to keep a list of errors rather than concatenating them as you go. That would help to maintain a separation of concerns between the logical errors and their presentation.

See how Spring validation works: you have an Errors object that keeps a list of errors, and a separate message source object that fills in the user-visible messages for the different errors.

Numismatist answered 6/11, 2013 at 13:38 Comment(2)
My problem is, i am working with legacy code. And i don't to touch whole setup just for sake of message formatting. Hope you understood my pain.Athenian
@Dark Knight: yes, understood completely.Numismatist
N
2

You could try using a PrintStream as it has an println(String string) method which add the new line automatically.

Something like this.

ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(bos);
ps.println("Line 1");
ps.println("Line 2");
ps.flush();
String message = new String(bos.toByteArray());
System.out.println(message);
Nahamas answered 6/11, 2013 at 13:42 Comment(0)
M
1

First of all you need to include the newline character(\n) at the end of every .append() yourself:

sb.append("paramX cannot be less than 10 \n");

As for repeating you new-line logic just wrap it in a method:

public void append(StringBuilder sb, Object value) {
    sb.append(value).append(System.getProperty("line.separator")).append('\n');
}

And use it like:

if(paramX < 10){
    append(sb, "paramX cannot be less than 10");
}
Monzonite answered 6/11, 2013 at 13:36 Comment(0)
G
-1

simply append directly...

        if(paramX<10){
            sb.append("paramX cannot be less than 10 \n ");
        }

        if(paramY<20){
            sb.append("paramY cannot be less than 20 \n ");
        }
Gauche answered 6/11, 2013 at 13:36 Comment(3)
Please read above post. I want to avoid manual padding. I would really appreciate if i get certain workaround which does not pad line formatting manually.Athenian
may be create your own function. but can't extend StringBuilder StringBuffer classes. Because it is final classes. so you create your custom function. but i think again you must use "\n" mannually.Gauche
Yes, you have to do this manually, or set up something more complicated with streams. The joys of java :DMiscegenation
K
-1

Just use \n - it will work everywhere. Also, it looks like you want to conditionally add a line feed if there are two messages:

StringBuilder sb = new StringBuilder();

if (paramX<10) {
    sb.append("paramX cannot be less than 10 ");
}

if (paramY<20) {
    if (!sb.length() > 0) // only add newline if needed
        sb.append('\n');
    sb.append("paramY cannot be less than 20 ");
}
Kopaz answered 6/11, 2013 at 13:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.