【问题标题】:java negate boolean BiFunctionjava negate boolean BiFunction
【发布时间】:2020-09-18 12:26:38
【问题描述】:

我有一个类可以检查一个键是否包含在一组键中。此条件在Map 中使用MathingTypes 进行了描述

public enum MatchingType {
    MATCH, MISMATCH
}

匹配类型谓词的映射

Map<MatchingType, Function<Set<String>, Predicate<String>>> predicateMap =
        Map.of(
                MATCH, set -> set::contains,
                MISMATCH, set -> not(set::contains)
        );

使用示例

public boolean isKeyAvailable(String key, MatchingType matchingType, Set<String> keys) {
    return predicateMap.get(matchingType)
                       .apply(keys)
                       .test(key);
}

现在我看到上面的代码可以使用BiFunction 进行重构。

Map<MatchingType, BiFunction<Set<String>, String, Boolean>> predicateMap =
        Map.of(
                MATCH, Set::contains,
                MISMATCH, Set::contains //how to negate?
        );

public boolean isKeyAvailable(String key, MatchingType matchingType, Set<String> keys) {
    return predicateMap.get(matchingType)
                       .apply(keys, key);
}

但是怎么可能否定Set::contains呢?

【问题讨论】:

    标签: java lambda java-8 functional-interface


    【解决方案1】:

    截至 有一个静态方法Predicate.not(Predicate) 但是BiPredicate 中没有这样的方法。

    您可能希望将BiPredicate 与其实例方法negate 一起使用,该方法自 发布以来可用:

    BiPredicate<Set<String>, String> biPredicate = Set::contains;
        
    Map<MatchingType, BiPredicate<Set<String>, String>> biPredicateMap =
        Map.of(
            MatchingType.MATCH, biPredicate,
            MatchingType.MISMATCH, biPredicate.negate()
        );
    
    boolean result = biPredicateMap.get(matchingType)
                                   .test(keys, key);
    

    基于 Function 的函数式接口没有否定,因为它们的 lambda 表达式不能保证返回 Boolean

    【讨论】:

    • 但是使用Map.of(MatchingType.MATCH, Set::contains, MatchingType.MISMATCH, (s,o) -&gt; !s.contains(o)) 并没有什么坏处。不知道为什么人们对方法引用如此着迷。
    • @Holger:也许 OP 的情况是 lambda 表达式太长了,方法参考会有很大帮助(这就是为什么我还建议将 biPredicatebiPredicateMap 分开放置field/variable 。请记住,我们总是被告知要发布一个 minimal 完整的可验证内容,这里看起来 !s.contains(o) 会更好。
    • 当有等效的方法引用表达式时,lambda 表达式怎么会太长?它总是归结为使用TypeName::methodName(a,b) -&gt; a.methodName(b)。我看不到任何情况下不惜一切代价使用方法参考是合理的。
    • 我不知道,只是猜测。我只回答了“但怎么可能否定 Set::contains?”我能做到的最好。我觉得这是一个偏好问题。此外,人们宁愿在一开始就监督! 运算符,而不是否定方法——这也是我的看法。
    猜你喜欢
    • 2012-10-16
    • 2011-09-07
    • 2014-12-16
    • 2021-10-23
    • 2020-01-21
    • 2021-06-23
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    相关资源
    最近更新 更多