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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:58:12  来源:igfitidea点击:

Java 8 lambda predicate chaining?

javalambdajava-8

提问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.

您可以移动单独的条件,以便以其他方式重新组合它们。