在方法引用的返回值上调用方法

fsp*_*rle 5 java java-8 java-stream

我有一个文件流,我想根据文件名的结尾过滤:

public Stream<File> getFiles(String ending) throws IOException {
    return Files.walk(this.path)
            .filter(Files::isRegularFile)
            .map(Path::toFile)
            .filter(file -> file.getName().endsWith(ending));
}
Run Code Online (Sandbox Code Playgroud)

虽然最后一行中的lambda也不错,但我认为我也可以在那里使用方法引用,如下所示:

 .filter(File::getName.endsWith(ending));
Run Code Online (Sandbox Code Playgroud)

或者用括号括起来.然而,这失败了The target type of this expression must be a functional interface

你能解释为什么这不起作用吗?

Rad*_*def 7

你能解释为什么这不起作用吗?

方法引用是l​​ambda表达式的语法糖.例如,方法引用File::getName(File f) -> f.getName().

Lambda表达式是"方法文字"用于定义功能接口的实施,例如Function,Predicate,Supplier等.

要使编译器知道您要实现的接口,lambda或方法引用必须具有目标类型:

// either assigned to a variable with =
Function<File, String> f = File::getName;
// or assigned to a method parameter by passing as an argument
// (the parameter to 'map' is a Function)
...stream().map(File::getName)...
Run Code Online (Sandbox Code Playgroud)

或者(异常地)投射到某物:

((Function<File, String>) File::getName)
Run Code Online (Sandbox Code Playgroud)

赋值上下文,方法调用上下文和强制转换上下文都可以为lambda或方法引用提供目标类型.(在上述所有3种情况中,目标类型为Function<File, String>.)

编译器告诉你的是你的方法引用没有目标类型,所以它不知道如何处理它.

  • 请注意,*classifier*:: functionName并不总是等同于(o - >*classifier*.functionName(*params*).*classifier*可以是例如表达式;在`getReference():: method`中,当赋值/强制转换函数类型时调用getReference()`,而在每次调用lambda时调用`o - > getReference().method(o)`,`getReference()`. (2认同)