StringBuilder append() and null values
Asked Answered
I

10

44

I have a list of Strings, and I want to concatenate them with spaces in between. So I'm using StringBuilder. Now if any of the Strings are null, they get stored in the StringBuilder literally as 'null'. Here is a small program to illustrate the issue:

public static void main(String ss[]) {
    StringBuilder sb = new StringBuilder();

    String s;
    s = null;

    System.out.println(sb.append("Value: ").append(s));
}

I'd expect the output to be "Value: " but it comes out as "Value: null"

Is there a way around this problem?

Ida answered 18/10, 2010 at 15:33 Comment(2)
what did you expect to happen?Callida
I know that I personally would expect a null string to be the same as an empty string since both have literally zero characters in the string and zero characters should get appended to the sb object. Ill bet the OP thought the same thing. I'm not saying it's the right thing, just that it is a reasonable answer to the question about what was expected.Craniotomy
V
35

You can do a check on the object before appending it:

sb.append("Value: ");
if (s != null) sb.append(s);
System.out.println(sb);

A key point to make is that null is not the same an an empty String. An empty String is still a String object with associated methods and fields associated with it, where a null pointer is not an object at all.

From the documentation for StringBuilder's append method:

The characters of the String argument are appended, in order, increasing the length of this sequence by the length of the argument. If str is null, then the four characters "null" are appended.

Vladimar answered 18/10, 2010 at 15:36 Comment(2)
thanks for the clarification :) , i forgot to look into the javadocsIda
Only problem with this is that if the last line of text just happens to be "null" (e.g. a text from a lawyer to a client: Mr Smith the court has decreed your marriage to now be null) then you lose the last line - and the most important word in the message . . .Racer
R
19

I'm not sure why you'd expect it to come out empty, given that the documentation is pretty clear:

If str is null, then the four characters "null" are appended.

Basically you need to either not call append at all if you have a null reference, or switch the value for "".

You could write a method to do this substitution if you find yourself doing it a lot:

public static String nullToEmpty(String text) {
    return text == null ? "" : text;
}

Indeed, I've just looked at the Guava documentation and the Strings class has exactly that method (but with a parameter called string instead of text).

Rigsby answered 18/10, 2010 at 15:40 Comment(0)
N
10

You can use commons-lang's StringUtils#defaultString():

sb.append("Value: ").append(StringUtils.defaultString(myVar));
Neckwear answered 16/4, 2013 at 22:59 Comment(1)
Perfect! This helps a bunch! While "null" is helpful sometimes, I really only wanted an empty string.Moonmoonbeam
M
10

With Java 8 you could also use the java.util.Optional class to provide a default value:

System.out.println(sb.append("Value: ").append(Optional.ofNullable(s).orElse("")));

Minnick answered 12/12, 2016 at 15:57 Comment(0)
L
4

In one line you can do:

System.out.println(sb.append("Value: ").append((s==null)?"":s));
Lientery answered 12/3, 2015 at 15:31 Comment(2)
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post.Blaseio
@MuhammadReda, I don't see how my answer does not provide a solution to the question. It's not a critique neither a clarification...so that's why I didn't put it on a comment... can you please explain yourself?Lientery
P
4
import java.util.Objects;
...
sb.append(Objects.toString(s, ""));

Uses Java internal utils, no external libs are needed. toString takes String, checks if it is null and if it is null, then returns specified default value, in this case "" (empty string), if it is not null it returns provided string.

Peloria answered 27/2, 2020 at 11:13 Comment(0)
D
0

For my purpose, I needed to generalize Answer #2 a little bit. Here is the same function, taking Object as argument, instead of String:

private String nullToEmpty(Object obj) {
    return obj == null ? "" : obj.toString();
}
Destiny answered 2/9, 2014 at 15:16 Comment(0)
N
0

I combined the answer from geeksforgeeks.org and @Benas.

map = map.entrySet()
    .stream()
    .peek(entry -> entry.setValue(Objects.toString(entry.getValue(), "")))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Objects from java.utils.

Newfoundland answered 29/9, 2022 at 12:59 Comment(0)
A
-1

Null check as @Shynthriir has mentioned is the simplest most efficient way (AFAIK) to get around the problem.

I would however strongly recommend initiating strings to an empty string String str = ""; instead, which would save you a lot of headache in a more complex programming effort.

Ashcan answered 18/10, 2010 at 15:39 Comment(0)
H
-1

You can do:

sb.Replace("= ,", "= null,");

or:

sb.append("Value: ").append((s != null)? s: "NULL");

Humidifier answered 17/3, 2021 at 10:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.