在 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:
?
就我而言,这很重要,因为我必须将 String
与 4 值、s1, s2, s3, s4
、这些值中的每一个 可能或不可能连接起来> 有null
值。
我在问这个问题因为我不想检查 s1 到 s4 的每个组合 (即检查这些变量是否为null
)或者最后用empty
String
替换"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<String>
。
您还可以在将字符串连接在一起时提供分隔符。
【讨论】:
这是连接字符串的好方法!另请注意,您可以使用 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 中连接空字符串的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章