【问题标题】:Java 8 nested null check for a string in a map in a listJava 8嵌套空检查列表中映射中的字符串
【发布时间】:2019-10-07 20:32:45
【问题描述】:

我需要执行一系列空值检查(嵌套空值检查)来获得如下所示的字符串数组

String[] test;
if(CollectionUtils.isNotEmpty(checkList)){
    if(MapUtils.isNotEmpty(checkList.get(0))){
        if(StringUtils.isNotBlank(checkList.get(0).get("filename"))){
            test = checkList.get(0).get("filename").split("_");
        }
    }
}

有没有更好的方法,比如使用 Java8 Optional,来执行这些嵌套检查?我尝试将 Optional 与 flatmap / map 一起使用,但没有成功。

【问题讨论】:

  • 我认为!checkList.isEmpty() 会返回一个 NPE。我想我必须做checkList!= null && !checkList.isEmpty(),所以我使用了另一个库。那么对于这个检查,我必须有嵌套的if() 语句吗?
  • return Optional.ofNullable(checkList) .filter(l -> !l.isEmpty()) .map(l -> l.get(0)) .filter(m -> !m.isEmpty()) .map(e -> e.getOrDefault("filename", "").split("_")) .orElse(new String[10]); 这样的东西不好,除非你知道为什么这些硬编码的值会浮动。
  • 首先不要让集合引用为null。然后,您不需要执行null 检查的第 3 方方法。

标签: java java-8 nested optional null-check


【解决方案1】:

您可以使用OptionalStream 操作的长链将输入逐步转换为输出。像这样的东西(未经测试):

String[] test = Optional.ofNullable(checkList)
    .map(Collection::stream)
    .orElseGet(Stream::empty)
    .findFirst()
    .map(m -> m.get("filename"))
    .filter(f -> !f.trim().isEmpty())
    .map(f -> f.split("_"))
    .orElse(null);

我强烈建议您停止使用null 列表和地图。使用 empty 集合而不是 null 集合要好得多,这样您就不必到处进行 null 检查。此外,不要让空字符串进入您的集合;将用户输入转换为内存对象后,尽早将它们过滤掉或用null 替换它们。您不想到处插入对trim()isBlank() 等的调用。

如果你这样做了,你可以简化为:

String[] test = checkList.stream()
    .findFirst()
    .map(m -> m.get("filename"))
    .map(f -> f.split("_"))
    .orElse(null);

好多了,不是吗?

【讨论】:

  • 谢谢。我同意不使用空列表和地图 - 但是...我从系统的其他部分接收这些数据,因此无法控制它。我会在这个假设下尝试上述方法,看看它是否适合我
  • 第一个效果很好。对于第二个,我正在尝试与生成列表的团队合作,看看他们是否可以进行更改以确保发送空列表或映射而不是 null .. 第二个也在我确保的测试用例上工作接收到的数据中不要有空值。
【解决方案2】:

不要嵌套ifs,而只是打开并反转它们:

String[] defaultValue = // let this be what ever you want

if(checkList == null || checkList.isEmpty()) {
    return defaultValue;
}

Map<String, String> map = checkList.get(0);
if(map == null || map.isEmpty()) {
    return defaultValue;
}

String string = map.get("filename");
if(string == null || string.trim().isEmpty()) {
    return defaultValue;
}

return string.split("_");

虽然这仅在您将此提取逻辑包装在方法中时才有效:

public static String[] unwrap(List<Map<String, String>> checkList) {
    ...
}

【讨论】:

    【解决方案3】:

    如果 checkList 为 null,则会在 CollectionUtils.isNotEmpty(checkList) 上抛出空指针异常。还使用内置的空检查器。 最好你应该编码

            if (null != checkList && !checkList.isEmpty() 
                    && null != checkList.get(0) && !checkList.get(0).isEmpty()
                    && StringUtils.isNotBlank(checkList.get(0).get("filename"))) {
    
                test = checkList.get(0).get("filename").split("_");
    
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-12
      • 2019-01-19
      • 2017-04-15
      • 1970-01-01
      • 2018-07-20
      • 2011-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多