Java 8 lambda谓词链接?

use*_*576 32 java lambda java-8

我无法编译它,甚至可以链接谓词lambdas?

Arrays.asList("1","2","3").stream().filter( (e -> e=="1" ).or(e-> e=="2") ).count();
Run Code Online (Sandbox Code Playgroud)

或者唯一的方法是显式创建一个谓词,然后像这样组合:

Predicate<String> isOne= e -> e=="1";
Arrays.asList("1","2","3").stream().filter( isOne.or(e -> e=="2") ).count();
Run Code Online (Sandbox Code Playgroud)

或者是否有更多"功能优雅"的方式来实现同样的目标?

Chr*_*ung 42

可以使用:

((Predicate<String>) e -> e.equals("1")).or(e -> e.equals("2"))
Run Code Online (Sandbox Code Playgroud)

但它不是很优雅.如果您在线指定条件,只需使用一个lambda:

e -> e.equals("1") || e.equals("2")
Run Code Online (Sandbox Code Playgroud)

  • Lambda表达式没有内在类型; 它们被转换为目标类型,必须是一个功能接口.这里的问题是它不知道使用第一个lambda表达式的目标类型.这个c;声; 它无法知道调用什么`或()`方法.此答案中的示例显示为第一个带有强制转换的lambda提供目标类型,这是重新注入所需类型信息的选项之一. (18认同)

Sar*_*ips 10

我正在研究类似的谓词链接问题,并提出了以下建议

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);
}
Run Code Online (Sandbox Code Playgroud)

链的第一个参数是lambda(Function),它返回一个lambda(Predicate),因此它需要几个箭头

public static void yourExample() {
    String[] filterVals = { "1", "2" };

    Arrays.asList("1","2","3")
        .stream()
        .filter(chain(x-> (y-> y.equals(x)), filterVals))
        .count();
}
Run Code Online (Sandbox Code Playgroud)

为了比较,这是我想要实现的......

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);
}
Run Code Online (Sandbox Code Playgroud)


小智 8

你可以使用魔术方法$:

<T> Predicate<T> $(Predicate<T> p) {
     return p;
}

Arrays.asList("1", "2", "3").stream().filter( $(e -> e=="1").or(e -> e=="2") ).count();
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一下,命名这个函数 $ 没有什么特别的意义。是的,如果你想让你的代码不可读...... (4认同)
  • 为什么要为此创建一个新方法呢?顺便说一下命名这个函数$没有特殊意义.无论如何,这也有效. (2认同)

Ant*_*iuc 5

这只是@Chris Jester-Young 答案的一个小补充。可以通过使用方法引用来缩短表达式:

((Predicate<String>) "1"::equals).or("2"::equals)
Run Code Online (Sandbox Code Playgroud)