使用anyMatch

时间:2018-08-15 07:23:31

标签: java string list null java-stream

这是针对以下问题:“ If statement - variable order for null safety

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

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

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))

2 个答案:

答案 0 :(得分:4)

您可以使用以下代码段:

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循环

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

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

答案 1 :(得分:0)

如果我正确理解问题,则getYesOrNoValue可能返回null。因此,要直接回答您的问题,只需将firstResponseValue的默认值为"NO"设为null

String dummy_method(List<Response> myList) {
    if (myList.isEmpty()) {
        return null; 
    }

    String firstResponseValue = Optional.ofNullable(myList.get(0).getYesOrNoValue())
            .orElse("NO");
    if ("NO".equalsIgnoreCase(firstResponseValue)) {
        return firstResponseValue; 
    }

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

但是您最好将其称为!"YES".equalsIgnoreCase(...),因为它实际上是在做什么。然后,您几乎可以完全丢弃firstResponseValue。然后您在Lino的答案上;-)


Aa和使用findFirst实现它的另一种方法:

String dummy_method(List<Response> myList) {
    if (myList.isEmpty()) {
        return null; 
    }

    myList.stream()
        .map(Response::getYesOrNoValue)
        .map(Optional::ofNullable)
        .map(answer -> answer.orElse("NO"))
        .filter("NO"::equalsIgnoreCase)
        .findFirst().orElse("YES");
}

您也可以用@Lino的.map()替换这两个value -> value == null ? "NO" : value。但是然后我将getYesOrNoValue返回一个Optional<String>,无论如何,它将切断对map的第二次呼叫。