StringBuilder append()和null值

44

我有一个字符串列表,我想用空格将它们连接起来。所以我使用StringBuilder。如果任何一个字符串是null,它们会被直接存储在StringBuilder中,字面上表示为“null”。下面是一个小程序,用于说明这个问题:

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

    String s;
    s = null;

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

我期望的输出结果是 "Value:",但实际上输出的是 "Value: null"。是否有解决这个问题的方法?


1
你期望发生什么? - phil294
3
我知道个人会认为空字符串和零长度的字符串是一样的,因为它们都没有字符,应该将零个字符附加到sb对象中。我敢打赌题目发布者也这样认为。我并不是说这是正确的做法,只是对于问题的预期答案是合理的回答。 - David Rector
10个回答

35

在将对象附加到其他内容之前,您可以对该对象进行检查:

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

需要强调的一点是null和空字符串不同。一个空字符串仍然是具有相关方法和字段的字符串对象,而null指针根本不是一个对象。

从StringBuilder的append方法文档中可以看到:

 

按顺序附加字符串参数的字符,将该序列的长度增加等于参数的长度。如果str为null,则附加四个字符“null”。


感谢澄清 :),我忘了查看Javadocs。 - look4chirag
1
唯一的问题是,如果文本的最后一行恰好是“null”(例如,律师发给客户的文本:“史密斯先生,法院已裁定您的婚姻现在无效”),那么您将失去最后一行 - 也就是信息中最重要的单词... - Trunk

19

我不确定为什么您会期望它为空,因为文档已经非常明确:

如果 str 是 null,则附加四个字符 "null"。

基本上,如果您有一个 null 引用,您需要完全不调用 append 或将其替换为 ""。

如果您发现自己经常这样做,可以编写一个方法进行此替换:

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

确实,我刚刚查看了Guava的文档,Strings类恰好有这个方法(但参数名为string而非text)。


10

太好了!这帮了我大忙!尽管“null”有时是有用的,但我真正想要的只是一个空字符串。 - Brian

10

使用Java 8,您还可以使用java.util.Optional类提供默认值:

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


4

一行代码可以实现以下功能:

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

这并没有提供问题的答案。如果要批评或请求作者澄清,请在他们的帖子下留言 - 您始终可以在自己的帖子上发表评论,并且一旦您拥有足够的声望,您将能够评论任何帖子 - Muhammad Reda
3
@MuhammadReda,我不明白我的答案为什么不能解决问题。这不是批评也不是澄清...所以我没有把它放在评论里...你能解释一下吗? - robert

4
import java.util.Objects;
...
sb.append(Objects.toString(s, ""));

使用 Java 内部工具,不需要外部库。 toString 接受 String,检查它是否为null,如果是null,则返回指定的默认值,本例中为""(空字符串),如果不是null,则返回提供的字符串。


0

针对我的需求,我需要稍微概括一下答案#2。这里是同样的函数,它以对象作为参数,而不是字符串:

private String nullToEmpty(Object obj) {
    return obj == null ? "" : obj.toString();
}

0

我结合了geeksforgeeks.org和@Benas的答案。

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

java.utils中的Objects


-1

如@Shynthriir所提到的,空值检查是解决问题最简单、最有效的方法(据我所知)。

然而,我强烈建议将字符串初始化为空字符串String str = "";,这将在更复杂的编程任务中为您节省很多麻烦。


-1

你可以做:

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

或者:

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


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