您尝试使用错误的接口类型。方式Function https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html在这种情况下不合适,因为它接收一个参数并有一个返回值。相反,你应该使用Consumer https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html(以前称为块)
函数类型声明为
interface Function<T,R> {
R apply(T t);
}
但是, Consumer 类型与您正在寻找的类型兼容:
interface Consumer<T> {
void accept(T t);
}
因此,Consumer 与接收 T 且不返回任何内容 (void) 的方法兼容。这就是你想要的。
例如,如果我想显示列表中的所有元素,我可以简单地使用 lambda 表达式为其创建一个使用者:
List<String> allJedi = asList("Luke","Obiwan","Quigon");
allJedi.forEach( jedi -> System.out.println(jedi) );
您可以在上面看到,在这种情况下,lambda 表达式接收一个参数并且没有返回值。
现在,如果我想使用方法引用而不是 lambda 表达式来创建这种类型的消费,那么我需要一个接收 String 并返回 void 的方法,对吧?
我可以使用不同类型的方法引用,但在这种情况下,让我们通过使用println
方法中的System.out
对象,像这样:
Consumer<String> block = System.out::println
或者我可以简单地做
allJedi.forEach(System.out::println);
The println
方法是合适的,因为它接收一个值并具有返回类型 void,就像accept
消费者中的方法。
因此,在您的代码中,您需要将方法签名更改为类似:
public static void myForEach(List<Integer> list, Consumer<Integer> myBlock) {
list.forEach(myBlock);
}
然后您应该能够在您的情况下使用静态方法引用创建一个消费者,方法是:
myForEach(theList, Test::displayInt);
最终,你甚至可以摆脱你的myForEach
方法完全并且简单地执行:
theList.forEach(Test::displayInt);
关于一等公民的职能
总而言之,事实是 Java 8 不会拥有一等公民的函数,因为结构函数类型不会添加到该语言中。 Java 将提供一种替代方法来从 lambda 表达式和方法引用创建函数接口的实现。最终 lambda 表达式和方法引用将绑定到对象引用,因此我们拥有的只是作为一等公民的对象。重要的是功能是存在的,因为我们可以将对象作为参数传递,将它们绑定到变量引用并将它们作为其他方法的值返回,然后它们几乎具有类似的目的。