java 8方法引用:`equals`或`equalsIgnoreCase`

时间:2017-05-02 18:43:00

标签: java-8 java-stream method-reference

我尝试转换方法boolean exists(String value, boolean isCaseSensitive)的正文:

    for(String str : existingNames){
        if(isCaseSensitive ? str.equals(name) : str.equalsIgnoreCase(name)){
            return true;
        }
    }

    return false;

使用java8方法引用的解决方案:

    Predicate<String> equalityPred = isCaseSensitive ? 
            name::equals : 
            name::equalsIgnoreCase;

    return existingNames.stream().anyMatch(equalityPred);

然后我看到这种方式在相反的方向上执行相等(例如value.equals(str)) 有没有办法解决这个问题,仍然使用方法引用,如果没有什么是java8方式。

2 个答案:

答案 0 :(得分:5)

平等没有“相反的方向”。唯一的问题可能是null值的行为。如果集合包含null,您的循环可能会失败,如果namenull,您的方法引用将失败。

您可以使用lambda表达式实现原始行为:

boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
    Predicate<String> equalityPred = isCaseSensitive? 
        s -> s.equals(name): 
        s -> s.equalsIgnoreCase(name);

    return existingNames.stream().anyMatch(equalityPred);
}

但如果null参数永远不相等,那么考虑name是没有意义的,因为如果集合包含{{NullPointerException,代码将会失败null 1}}。

要为null获得明智的行为,您可以使用

boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
    Predicate<String> equalityPred = name==null? Objects::isNull:
        isCaseSensitive? name::equals: name::equalsIgnoreCase;

    return existingNames.stream().anyMatch(equalityPred);
}

或只是

boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
    return name==null || isCaseSensitive?
        existingNames.contains(name):
        existingNames.stream().anyMatch(name::equalsIgnoreCase);
}

如果您知道该集合永远不会包含null,但希望支持null name参数,那么您也可以使用

boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
    return name!=null && existingNames.stream()
        .anyMatch(isCaseSensitive? name::equals: name::equalsIgnoreCase);
}

答案 1 :(得分:3)

那么不要使用方法引用然后直接编写lambda:

     static boolean existsJDK8(List<String> existingNames, String value, boolean isCaseSensitive) {
         Predicate<String> equalityPred = isCaseSensitive ? s -> value.equals(s) : s -> value.equalsIgnoreCase(s);

         Predicate<String> equalityPredReversed = isCaseSensitive ? s -> s.equals(value) : s -> s.equalsIgnoreCase(value);

         // return  existingNames.stream().anyMatch(equalityPredReversed);
        return existingNames.stream().anyMatch(equalityPred);
     }