首页 > 解决方案 > 使用 anyMatch 的流中的空安全性

问题描述

这是一个后续问题:“ If 语句 - 空安全的变量顺序

假设我有一个“响应”对象列表。这包括一个表示“YES”或“NO”的字符串值。

如果所有成员都回答“是”,则返回“是”。如果至少一名成员回答“否”,则返回“否”。换句话说,如果列表包含“YES”和“NO”响应的混合,则答案为“NO”。否则,答案是“是”。(假设“是”和“否”是唯一的选项)。

String dummy_method(List<Response> myList) {
    if(myList.isEmpty()) {
        return null; 
    }
    String firstResponseValue = myList.get(0).getYesOrNoValue(); 
    if ("NO".equalsIgnoreCase(firstResponseValue)) {
        return firstResponseValue; 
    }
    return myList.stream.anyMatch(response -> !response.getYesOrNoValue().equalsIgnoreCase(firstResponseValue)) ? "NO" : firstResponseValue;
}

是否有一种“优雅”的方式来确保最后一个 return 语句中的 null 安全性:

return myList.stream.anyMatch(response -> !response.getYesOrNoValue().equalsIgnoreCase(firstResponseValue)) ? "NO" : firstResponseValue;

比如与

if ("NO".equalsIgnoreCase(firstResponseValue))

标签: javastringlistnulljava-stream

解决方案


您可以使用以下代码段:

String dummy_method(List<Response> myList){
    final boolean allMatch = myList.stream()
        .map(Response::getYesOrNoValue)
        .allMatch("YES"::equals);

    return allMatch ? "YES" : "NO";
}

的使用allMatch与使用倒置的相同anyMatch,我只是更喜欢前者,但你也可以这样写:

String dummy_method(List<Response> myList){
    final boolean anyMatch = myList.stream()
        .map(Response::getYesOrNoValue)
        .map(value -> value == null ? "NO" : value) // since we compare to "NO", we have to convert nulls
        .anyMatch("NO"::equals); // changed from "YES" to "NO"

    return anyMatch ? "NO" : "YES"; // flipped "YES" and "NO"
}

两者都是短路的,因此它们的行为完全相同。


您也可以使用for-loop

String dummy_method(List<Response> myList){
    for(Response response : myList){
        if(response != null && "NO".equals(response.getYesOrNoValue())){
            return "NO";
        }
    }
    return "YES";
}

这可能是所有三个中最简单和最易读的解决方案。


推荐阅读