【问题标题】: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

标签: java string concat


【解决方案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, ""));
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-03
          相关资源
          最近更新 更多