在一个语句中使用和/或/否定方法创建谓词?

时间:2016-03-12 12:06:39

标签: java functional-programming java-8 predicate method-reference

java.util.function.Predicate有一些有用的方法,例如andor等,这些方法比使用多个逻辑运算符创建一个方括号更简洁。不幸的是,似乎没有办法使用这些函数而没有实际上明确地首先使用谓词......

Predicate<String> predicate = String::isEmpty;
Predicate<String> predicateWithAnd = predicate.and( MyClass::testSomething ); 

有没有办法只在一个语句中创建第二个谓词(因此&#34;保存&#34;一个变量),比如......

Predicate<String> predicateWithAnd = (String::isEmpty).and( MyClass::testSomething );  // That doesn't seem to work ;-)

好奇......

2 个答案:

答案 0 :(得分:6)

是的,你需要在Predicate类型上施放lambda,其中T是你的类型。使用Person类的示例。

Predicate<Person> a = ((Predicate<Person>)p -> p.getId() > 2)
                                     .and(p -> p.getPrice() > 100);

答案 1 :(得分:4)

不清楚为什么str -> str.isEmpty() && MyClass.testSomething(str)被称为&#34;支架狂欢&#34;。它的可读性和简短性。通常,当您准备好and个对象时,这些orPredicate方法非常有用。您不应该使用它们来组合方法引用或lambdas。

如果你真的想使用方法引用,那么很少有技巧。首先,您可以创建自己的实用程序类:

import java.util.function.Predicate;
import java.util.stream.Stream;

public class Predicates {
    @SafeVarargs
    public static <T> Predicate<T> and(Predicate<T>... preds) {
        return Stream.of(preds).reduce(Predicate::and).orElse(x -> true);
    }

    @SafeVarargs
    public static <T> Predicate<T> or(Predicate<T>... preds) {
        return Stream.of(preds).reduce(Predicate::or).orElse(x -> false);
    }
}

并像这样使用它:

import static mypackage.Predicates.*;

Predicate<String> predicateWithAnd = and(String::isEmpty, MyClass::testSomething);

或者,您可以只创建一个非常无用的静态方法:

public static <T> Predicate<T> pred(Predicate<T> pred) {
    return pred;
}

并像这样使用它:

pred(String::isEmpty).and(MyClass::testSomething);

这比显式类型转换短得多。但是我仍然建议保留像str -> str.isEmpty() && MyClass.testSomething(str)这样的显式lambda。