java.util.function.Predicate
有一些有用的方法,例如and
,or
等,这些方法比使用多个逻辑运算符创建一个方括号更简洁。不幸的是,似乎没有办法使用这些函数而没有实际上明确地首先使用谓词......
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 ;-)
好奇......
答案 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
个对象时,这些or
,Predicate
方法非常有用。您不应该使用它们来组合方法引用或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。