如何将多个谓词应用于java.util.Stream's filter()方法?
这就是我现在所做的,但我并不喜欢它.我有一些Collection东西,我需要根据Collection过滤器(谓词)减少事物的数量:
Collection<Thing> things = someGenerator.someMethod();
List<Thing> filtered = things.parallelStream().filter(p -> {
for (Filter f : filtersCollection) {
if (f.test(p))
return true;
}
return false;
}).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
我知道如果我事先了解过滤器的数量,我可以这样做:
List<Thing> filtered = things.parallelStream().filter(filter1).or(filter2).or(filter3)).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
但是如何在不混合编程风格的情况下应用未知数量的谓词?知道它看起来有点难看......
这与这个问题有关:如何进行功能组合?
我注意到方法引用可以分配给声明为的变量Function,因此我假设它应该具有andThen或compose函数,因此我希望我们可以直接组合它们.但很显然,我们需要把它们分配给声明为可变的Function第一(或类型转换调用之前)之前,我们可以称之为andThen或compose他们.
我怀疑我可能会对这应该如何运作有一些误解.
所以我的问题:
andThen方法之前,为什么我们需要先键入或将其分配给变量?示例代码如下.
public class MyMethods{
public static Integer triple(Integer a){return 3*a;}
public static Integer quadruple(Integer a){return 4*a;}
public int operate(int num, Function<Integer, Integer> f){
return f.apply(num);
}
public static void main(String[] args){
MyMethods methods = new MyMethods();
int three = methods.operate(1, MyMethods::triple); // This is fine
// Error below
// int twelve = methods.operate(1, (MyMethods::triple).andThen(MyMethods::quadruple));
// But this one is …Run Code Online (Sandbox Code Playgroud) 在当前的JSR 335草案中,它在0.6.0的更改日志条目中提到它"消除了对未绑定的内部类构造函数引用的支持".
为了说明,假设您有一个名为的外部类A和一个名为的内部类B,并且您需要一个接受A并创建新B实例的函数:
Function<A, A.B> foo = a -> a.new B();
Run Code Online (Sandbox Code Playgroud)
在0.6.0之前,您还可以使用构造函数引用语法来执行相同的操作(甚至在Lambda的状态中记录):
Function<A, A.B> foo = A.B::new;
Run Code Online (Sandbox Code Playgroud)
如上所述,0.6.0不再支持该语法.我真的很想知道为什么.
我已经通过档案的看着lambda-spec-experts和lambda-dev邮件列表,并不能找到任何关于它的信息.
java.util.function.Predicate有一些有用的方法等and,or等,其比创建具有多个逻辑运算符的托架狂欢更简洁.不幸的是,似乎没有办法使用这些函数而没有实际上首先明确地使用谓词...
Predicate<String> predicate = String::isEmpty;
Predicate<String> predicateWithAnd = predicate.and( MyClass::testSomething );
Run Code Online (Sandbox Code Playgroud)
有没有办法只在一个语句中创建第二谓词(因此"保存"变量),如...
Predicate<String> predicateWithAnd = (String::isEmpty).and( MyClass::testSomething ); // That doesn't seem to work ;-)
Run Code Online (Sandbox Code Playgroud)
只是好奇...
java functional-programming predicate java-8 method-reference
通过 Java 8 中引入的函数式接口,您可以轻松地将不同的表达式链接到一个新表达式中,如下面的代码片段所示。
public class PredicateChaining {
public static void main(String[] args) {
// verbose, but standard JDK functionality only
Predicate<String> allUpperCase = StringUtils::isAllUpperCase;
Predicate<String> longerThan5 = s -> s.length() > 5;
if (allUpperCase.and(longerThan5).test("PREDICATE")) {
System.out.println("'PREDICATE' is a uppercase text, longer than 5.");
}
// compact, but with utility method ('chain' in this case)
if (chain(StringUtils::isAllLowerCase).and(s -> s.length() < 5).test("test")) {
System.out.println("'test' is a lowercase text, shorter than 5.");
}
}
public static <T> Predicate<T> chain(Predicate<T> test) {
return …Run Code Online (Sandbox Code Playgroud)