如何确定一个字符串列表是否包含空元素或空字符串

28

我在Java中有以下方法:

public String normalizeList(List<String> keys) {
    // ...
}

我想要检查keys

  • 不是null本身;并且
  • 不是空的(size() == 0);并且
  • 没有任何String元素是null;并且
  • 没有任何String元素是空的(“”)

这是一个实用方法,将会放在类似于DataUtils的“commons”风格的JAR中。以下是我的代码,但我认为它是错误的:

public String normalize(List<String> keys) {
    if(keys == null || keys.size() == 0 || keys.contains(null) || keys.contains(""))
        throw new IllegalArgumentException("Bad!");

    // Rest of method...
}

我认为最后两个检查keys.contains(null)keys.contains("")是不正确的,很可能会引发运行时异常。我知道我可以在if语句内部遍历列表,并在那里检查null/空值,但如果存在更优雅的解决方案,我想尝试一下。


我认为对于keys.contains(null)和keys.contains("")的最后两个检查是不正确的,很可能会抛出运行时异常。为什么?你期望会抛出什么异常? - assylias
keys.contains(null) 是可以的,但是 keys.contains("") 只在某些情况下有效,但不应该抛出异常。 - Kevin Mangold
1
兄弟,你的应用程序里有太多的空值了... - Louis Wasserman
4
文档指出可能会抛出NPE异常。无论如何,一些List的实现使用Collection#contains方法,这让我相信文档所说的。 - Roman C
9个回答

41
 keys.contains(null) || keys.contains("")

如果你的列表包含null或空字符串,则不会抛出任何运行时异常,并且结果为true


21
这个解决方案存在问题,因为如果列表不允许包含null值,List.contains方法可能会抛出NullPointerException异常。例如:List.of("foo", "bar").contains(null)会抛出异常! - James Marble
1
请查看我的评论,了解如何使用org.springframework.util.CollectionUtils来解决NullPointerException问题。 - Denis Orlov

8

在 Java 8 中,您可以实现以下功能:

public String normalizeList(List<String> keys) {
    boolean bad = keys.stream().anyMatch(s -> (s == null || s.equals("")));
    if(bad) {
        //... do whatever you want to do
    }
}

3
如果(keys.stream().anyMatch(String::isBlank)){...}。String::isBlank 是自Java11以来的新特性。 - Aniket Sahrawat

7

在我看来,这看起来很好,你只会从 keys.contains(null)keys.contains("") 中得到异常,如果 keys 本身是 null

然而,由于您首先检查了它,因此您知道此时的 keys 不是 null,因此不会发生运行时异常。


1

如果你能使用org.springframework.util.CollectionUtils,你可以应用以下内容:

if(CollectionUtils.isEmpty(coll) || CollectionUtils.containsInstance(coll, null)) {
        // throw ...;
}

对于像List.of()这样的不可变集合,它不会抛出NullPointerException。


0

这仅适用于一个字符串,而不是整个列表。 - user666

0
boolean badListInRequest = CollectionUtils.isEmpty(request.getIdList()) ||
                request.getIdList().stream().anyMatch(s -> (StringUtils.isBlank(s)));

if(badListInRequest){
    throw new Exception...
}

0

Aniket在评论中给出了一个非常好的答案:

if( keys.stream().anyMatch(String::isBlank) ) { .... String::isBlank is since Java11. – 
Aniket Sahrawat
Apr 6, 2019 at 2:30

所以根据Aniket的评论来调整您的原始解决方案:

public String normalize(List<String> keys) {
    if(keys == null || keys.size() == 0  || keys.stream().anyMatch(String::isBlank)){
        throw new IllegalArgumentException("Bad!");
    }

    // Rest of method...
}

0

我不确定,但是在ApacheCommon库中是否有任何辅助类可以做到这一点?就像当您拥有字符串的isEmpty时,您在ApacheCommons库中拥有isNullOrEmpty一样。


0

一次遍历中检查列表

  public static boolean empty(String s) {
    if (s == null)
      return true;
    else if (s.length() == 0)
      return true;
    return false;
  }  

  public String normalize(List<String> keys) {
    if(keys == null || keys.size() == 0)
        throw new IllegalArgumentException("Bad!");
    for (String key: keys)
      if(empty(key))
         throw new IllegalArgumentException("Empty!");

    // Rest of method...
    return null;
  }

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