Java 8 lambda 谓词链接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24396544/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 lambda predicate chaining?
提问by user1606576
I can't get it to compile, is it even possible to chain predicate lambdas?
我无法编译它,甚至可以链接谓词 lambdas 吗?
Arrays.asList("1","2","3").stream().filter( (e -> e=="1" ).or(e-> e=="2") ).count();
Or only way is to explicitly create a predicate and then combine like so:
或者唯一的方法是显式创建一个谓词,然后像这样组合:
Predicate<String> isOne= e -> e=="1";
Arrays.asList("1","2","3").stream().filter( isOne.or(e -> e=="2") ).count();
Or is there more "functionally elegant" way to achieve same thing?
或者是否有更多“功能优雅”的方式来实现同样的事情?
采纳答案by Chris Jester-Young
You canuse:
您可以使用:
((Predicate<String>) e -> e.equals("1")).or(e -> e.equals("2"))
but it's not very elegant. If you're specifying the conditions in-line, just use one lambda:
但它不是很优雅。如果您在线指定条件,只需使用一个 lambda:
e -> e.equals("1") || e.equals("2")
回答by Sarah Phillips
I was working on a similar problem of predicate chaining and came up with the following
我正在研究谓词链接的类似问题,并提出以下
public static <T> Predicate<T> chain (Function<T,Predicate<T>> mapFn, T[]args) {
return Arrays.asList(args)
.stream()
.map(x->mapFn.apply(x))
.reduce(p->false, Predicate::or);
}
The first parameter to chain is a lambda (Function) that returns a lambda (Predicate) so it needs a couple of arrows
链接的第一个参数是一个 lambda(函数),它返回一个 lambda(谓词),所以它需要几个箭头
public static void yourExample() {
String[] filterVals = { "1", "2" };
Arrays.asList("1","2","3")
.stream()
.filter(chain(x-> (y-> y.equals(x)), filterVals))
.count();
}
For comparison, here is what I was trying to achieve...
为了进行比较,这就是我试图实现的目标......
public static void myExample() {
String[] suffixes = { ".png", ".bmp" };
Predicate<String> p = chain (x-> y-> y.endsWith(x), suffixes);
File[] graphics = new File("D:/TEMP").listFiles((dir,name)->p.test(name));
Arrays.asList(graphics).forEach(System.out::println);
}
回答by Vitaliy Oliynyk
You can use with magic method $:
您可以使用魔术方法 $:
<T> Predicate<T> $(Predicate<T> p) {
return p;
}
Arrays.asList("1", "2", "3").stream().filter( $(e -> e=="1").or(e -> e=="2") ).count();
回答by Anton Balaniuc
This is just a small addition to @Chris Jester-Young answer. It is possible to make the expression shorter by using method reference:
这只是@Chris Jester-Young 答案的一个小补充。可以通过使用方法引用来缩短表达式:
((Predicate<String>) "1"::equals).or("2"::equals)
回答by Алексей Лумпов
Arrays.asList("1","2","3").stream().filter( Arrays.asList("1", "2")::contains).count();
and yes method "either" is good idea
是的方法“要么”是个好主意
public static void main(String[] args) {
long count = Arrays.asList("1","2","3").stream().filter(either("1"::equals).or("2"::equals)).count();
System.out.println(count);
}
private static <T> Predicate<T> either(Predicate<T> predicate) {
return predicate;
}
or you can use import static java.util.function.Predicate.isEqual;
and write isEqual("1").or(isEqual("2"))
或者你可以使用import static java.util.function.Predicate.isEqual;
和写isEqual("1").or(isEqual("2"))
回答by Dale krebbers
Predicate<String> pred1 = "1"::equals;
Predicate<String> pred2 = "2"::equals;
public void tester(){
Arrays.asList("1","2","3").stream().filter(pred1.or(pred2)).count();
}
You can move your separate your conditions to make it possible to recombine them other ways.
您可以移动单独的条件,以便以其他方式重新组合它们。