如何最好地确定一个字符串是否只包含 null 字符?

5

如何正确地检查一个字符串是否仅包含空字符?

String s = "\u0000";
if(s.charAt(0) == 0) {
   System.out.println("null characters only");
}

或者

String s = "\0\0";
for(int i = 0; i < s.length(); i++) {
   if(s.charAt(i) == 0) 
       continue;

   else break;

}

两者都可行。但是否有更好、更简洁的方法来执行此检查?是否有一种工具可以检查Java字符串是否仅包含空(\u0000\0)字符?

'\0''\u0000'之间有什么区别呢?


4
嗯,我很难想到一种合理的用例需要测试字符串是否只包含空字符(NUL)。 (我能想到的唯一用例涉及将非文本数据视为文本...而这在概念上是错误的。) - Stephen C
@StephenC,我的服务需要调用下游服务器,该服务器在JSON主体中返回一个参数,称为“eCode”,基于此,我需要检查下游服务器是否出现了问题,因此如果此字符串为空或仅包含空字符,则一切正常,否则,如果“eCode”包含任何其他内容,则我需要向上游返回错误响应。 - tusharRawat
1
好的...那么为什么服务器在JSON响应中发送包含NUL字符的字符串给你呢?这...嗯...是不好的设计。你确定你没有误解规范吗?(它实际上可能是说“空字符串或null”吗?JSON中有一个null值。) - Stephen C
我甚至已经测试了调用服务,它们返回的是空字符字符串。起初我以为应该是null或""空字符串,但当我的测试用例失败时,我意识到它们返回了其他东西,这确实是一个糟糕的设计,我同意。但你知道,我必须处理它,因为我没有其他服务的所有权。 - tusharRawat
7个回答

9

在Java中,char字面值可以有多种写法(它们都是等效的)。例如,

System.out.println('\u0000' == '\0');
System.out.println('\u0000' == 0);

将产生输出

true
true

因为在Java中,char是一个16位整数类型,而且这三个值:\u0000\00的值都相同。至于如何判断一个String是否只包含0 char值,可以通过迭代方式实现。例如:
boolean allNulls = true;
for (int i = 0; i < s.length(); i++) {
    if (s.charAt(i) != 0) {
        allNulls = false;
        break;
    }
}

2
如果你想要一种简洁的方法来进行测试,可以将上述代码放入一个方法/函数中。 - Stephen C
1
@tusharRawat,“util”是什么意思?无论你使用什么,都会在某个时候循环遍历字符串的每个字符。只是你可能看不到你编写的代码中的循环。毕竟,如果没有检查每一个字符,你怎么知道每个字符是否为NUL呢? - Sweeper
1
在这种情况下,我要参考Stephen C对你的问题的评论 - 这根本不是一件常见的事情(也有可能你根本不应该这样做)。没有理由存在这样的实用程序。我的答案或user15793316的答案可能是你能得到的最短的解决方案。 - Sweeper
1
@Sweeper 这并不是更好的方法(因为它会创建临时变量),但是 if (s.replaceAll("\u0000", "").length() == 0) { /* */ } 更短。至少我认为是这样的。 - Elliott Frisch
1
@ElliottFrisch为什么开发人员经常想出创造性的绕路,而未能直接使用表达意图的方法?当您想要检查字符串是否与某个模式匹配时,只需使用s.matches("\0*"),而不是用空字符串替换匹配项(replaceAll也使用正则表达式引擎),然后测试是否只剩下空字符串。如果您担心临时对象,请使用Pattern.compile(...)来重用构造真正昂贵的部分(Matcher可以忽略)。 - Holger
显示剩余4条评论

5
你可以将chars()作为一个IntStream获取,然后使用allMatch
if (yourString.chars().allMatch(x -> x == 0)) {
    // all null chars!
}

3
你可以使用正则表达式来匹配一个或多个 \u0000
boolean onlyNulls = string.matches("\u0000+");  // or "\0+"

使用*代替+也可以匹配空字符串


solution的流 {{by Sweeper}} 是我首选的解决方案 - 个人认为,它更符合预期任务,尽管我会使用'\u0000'而不是0


0

除了其他答案(都是有效的),我刚刚找到了一个基于org.apache.commons.lang3.StringUtils的一行代码:

StringUtils.containsOnly(<string>, '\u0000')

注意:此方法管理返回空字符串 "" 的情况,使其返回 true


0

我认为没有预定义的方法来检查它,我认为你提到的第二种方式是测试相同的正确方式。


-1
你可以使用现有的字符串方法,如trimisEmpty来进行组合。 考虑以下内容:
String s = "\u0000";
s.trim().isBlank()

但是对于\t\r和其他全空格输入也同样适用。 - Tim Biegeleisen
是的,它会,我还没有考虑到这一点。 - Meetesh
1
当您在代码示例中使用isBlank()时,先执行trim()没有意义。只有在使用isEmpty()时才需要执行trim(),这是您答案的第一句话所描述的情况。 - Holger

-1

\u0000 是 Unicode 值,控制台输出为空格

Stream.of("\u0000","\0\0","jack", "luca")
  .filter(s -> !s.trim().equals(""))
  .forEach(System.out::println);

输出:

jack
luca

这是不正确的,因为它也会打印出包含非NUL字符的某些字符串的“true”。 - Stephen C
1
\u0000 的控制台输出取决于特定的控制台。 - Holger

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