在 Java 中连接空字符串的正确方法是啥?

Posted

技术标签:

【中文标题】在 Java 中连接空字符串的正确方法是啥?【英文标题】:What is the right approach to concatenating a null String in Java?在 Java 中连接空字符串的正确方法是什么? 【发布时间】:2014-08-26 08:02:10 【问题描述】:

我知道以下几点:

String s = null;
System.out.println("s: " + s);

将输出:s: null

如何让它只输出s: ​

就我而言,这很重要,因为我必须将 String4 值、s1, s2, s3, s4这些值中的每一个 可能或不可能连接起来> 有null

我在问这个问题因为我不想检查 s1 到 s4 的每个组合 (即检查这些变量是否为null或者最后用emptyString替换"null",因为我认为可能有更好的方法来做到这一点。

【问题讨论】:

一个有趣的事实(这不是您问题的答案):考虑到 Java 语言的繁琐程度,字符串连接永远不会为 null 抛出异常可能会让人感到惊讶,即使如果您在 null 本身上使用 +=。例如:String s = null; s += null;。在这两个语句之后,s 成为明显非null 字符串"nullnull"。连接不是null,但其toString() 方法被重写为return null 的对象也是安全的。在所有情况下,串联都用"null" 替换null 在 Stack Overflow 推出近 6 年后,这怎么不是重复的? “空字符串”和“空引用”是有区别的。 “空字符串”是"",将打印为空。 null reference 甚至不是 String。 @PeterMortensen - 我试图找到一个骗子,但每次搜索都会找到null 相关:Concatenating null strings in Java 【参考方案1】:

试试这个

String s = s == null ? "" : s;
System.out.println("s: " + s);

当没有任何对象分配给变量时,字符串变量(此处为s)被称为null。所以用一个空字符串初始化变量"";然后你可以连接字符串。

如果您的 s 变量可能为 null 或不为 null,请在进一步使用之前使用条件运算符。那么变量s 不再为空。

这是一个示例代码:

    String s1 = "Some Not NULL Text 1 ";
    String s2 = null;
    String s3 = "Some Not NULL Text 2 ";

    s1 = s1 == null ? "" : s1;
    s2 = s2 == null ? "" : s2;
    s3 = s3 == null ? "" : s3;

    System.out.println("s: " + s1 + s2 + s3);

样本输出:

s: Some Not NULL Text 1 Some Not NULL Text 2

【讨论】:

这不是我想要的。 @REACHUS 我更改了代码,使用 s = s == null ? “”:s;从空字符串中恢复的语句 @REACHUS 用给出的输出检查你的问题?【参考方案2】:

您可以使用Apache Commons StringUtils.defaultString(String) 方法,或者如果您不使用任何第三方库,您甚至可以编写自己的方法,这只是一个衬里。

private static String nullToEmptyString(String str) 
    return str == null ? "" : str;

然后在你的系统输出中使用它:

System.out.println("s: " + nullToEmptyString(s));

【讨论】:

【参考方案3】:
String s = null;
System.out.println("s: " + (s != null ? s : ""));

但您真正要求的是null coalescing operator。

【讨论】:

C#: "s: " + (s ?? "") C#:"s: " + s。 .NET 不打印null。 .NET 在 Java 之后出现。许多 Java 错误没有重演。【参考方案4】:

你可以为concatenation声明你自己的方法:

public static String concat(String... s) 
//Use varArgs to pass any number of arguments
    if (s!=null) 
       StringBuilder sb = new StringBuilder();
       for(int i=0; i<s.length; i++) 
          sb.append(s[i] == null ? "" : s[i]);
       
       return sb.toString();
    
    else 
        return "";
    

【讨论】:

【参考方案5】:

最简洁的解决方案是:

System.out.println("s: " + (s == null ? "" : s));

或者创建或使用静态辅助方法来做同样的事情;例如

System.out.println("s: " + denull(s));

但是,这个问题有过度使用/误用null 的应用程序的“味道”。如果 null 具有与非空值的含义不同(并且需要不同)的特定含义,则最好仅使用/返回它。

例如:

如果这些空值来自默认初始化为null 的字符串属性,请考虑将它们显式初始化为""。 不要使用null 表示空数组或集合。 在最好抛出异常时不要返回null。 考虑使用Null Object Pattern。

现在显然所有这些都有反例,有时您必须处理一个预先存在的 API,它会为您提供空值......无论出于何种原因。但是,根据我的经验,最好避免使用 null ... 大多数时间。

因此,在您的情况下,更好的方法可能是:

String s = "";  /* instead of null */
System.out.println("s: " + s);

【讨论】:

java.util.Objects.toString(obj, default)denull() 的库等价物。以及关于空值的总体好建议。 +1。 @StuartMarks - 它与denull 做同样的事情。但是特殊用途的辅助方法会更简洁。 我将这个特殊用途的辅助函数命名为“nullToEmpty(...)”,但它在语义上与“deNull(...)”相同 OP 显然正在寻找一种简洁的方法来进行测试,我正在迎合这一点。【参考方案6】:

您可以在 Java 8 中使用以下内容:

String s1 = "a";
String s2 = null;
String s3 = "c";
String s4 = "d";
String concat = Stream.of(s1, s2, s3, s4)
        .filter(s -> s != null)
        .collect(Collectors.joining());

给予

abc

需要注意的几点:

您可以将数据结构(列表等)直接转换为Stream&lt;String&gt;。 您还可以在将字符串连接在一起时提供分隔符。

【讨论】:

这是连接字符串的好方法!另请注意,您可以使用 StringUtils 的功能接口进行空检查,例如: .filter(StringUtils::isNotBlank) 不错!但是,您可以将 lambda 替换为方法引用“Objects::nonNull”。【参考方案7】:

想到了两种方法,第一种不使用连接,但最安全:

public static void substituteNullAndPrint(String format, String nullString, Object... params)
    String[] stringParams = new String[params.length()];
    for(int i=0; i<params.length(); i++)
        if(params[i] == null)
            stringParams[i] = nullString;
        else
            stringParams[i] = params[i].toSTring();
        
    

    String formattedString = String.format(format, stringParams);
    System.out.println(formattedString);


USAGE:
substituteNullAndPrint("s: %s,%s", "", s1, s2);

第二个使用连接,但要求您的实际字符串永远不会包含“null”,因此它可能仅适用于非常简单的情况(无论如何,即使您的字符串永远不是“null”,我也永远不会使用它):

public static void substituteNullAndPrint(String str)
    str.replace("null", "");
    System.out.println(str);


USAGE:
substituteNullAndPrint("s: " + s1);

注意事项:

-两者都使用外部实用方法,因为我反对内联大量条件。

-这未经测试,我可能会将 c# 语法与 Java 混淆

【讨论】:

【参考方案8】:

另一种方法是使用在 Java 7 中添加的java.util.Objects.toString()

String s = null;
System.out.println("s: " + Objects.toString(s, ""));

这适用于任何对象,而不仅仅是字符串,当然您可以提供另一个默认值而不仅仅是空字符串。

【讨论】:

以上是关于在 Java 中连接空字符串的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

为 HSQLDB 中的列指定默认空字符串的正确方法?

检查“不为空”或空字符串的 PHP 语法是啥? [复制]

PB中取字符串子串的函数是啥

PB中取字符串子串的函数是啥

匹配重写规则的空字符串的正则表达式是啥?

Java中字符串中子串的查找共有四种方法(indexof())