本文翻译自:How do I define a method which takes a lambda as a parameter in Java 8?
In Java 8, methods can be created as Lambda expressions and can be passed by reference (with a little work under the hood). 在Java 8中,可以将方法创建为Lambda表达式,并可以通过引用将其传递(在后台进行一些工作)。 There are plenty of examples online with lambdas being created and used with methods, but no examples of how to make a method taking a lambda as a parameter. 在线上有很多示例,其中创建了lambda并将其与方法一起使用,但没有如何使用lambda作为参数的方法的示例。 What is the syntax for that? 它的语法是什么?
MyClass.method((a, b) -> a+b);
class MyClass{
//How do I define this method?
static int method(Lambda l){
return l(5, 10);
}
}
#1楼
参考:https://stackoom.com/question/v5Ch/在Java-中-如何定义将lambda作为参数的方法
#2楼
Lambdas are purely a call-site construct: the recipient of the lambda does not need to know that a Lambda is involved, instead it accepts an Interface with the appropriate method. Lambda纯粹是一个呼叫站点构造:Lambda的接收者不需要知道一个Lambda,而是使用适当的方法接受一个Interface。
In other words, you define or use a functional interface (ie an interface with a single method) that accepts and returns exactly what you want. 换句话说,您定义或使用一个功能接口(即具有单个方法的接口)来接受并返回您想要的内容。
For this Java 8 comes with a set of commonly-used interface types in java.util.function (thanks to Maurice Naftalin for the hint about the JavaDoc). 为此,Java 8在java.util.function附带了一组常用的接口类型(感谢Maurice Naftalin提供有关JavaDoc的提示)。
For this specific use case there's java.util.function.IntBinaryOperator with a single int applyAsInt(int left, int right)
method , so you could write your method
like this: 对于此特定用例,有一个 java.util.function.IntBinaryOperator
,它具有一个int applyAsInt(int left, int right)
方法 ,因此您可以这样编写method
:
static int method(IntBinaryOperator op){
return op.applyAsInt(5, 10);
}
But you can just as well define your own interface and use it like this: 但是您也可以定义自己的接口并像这样使用它:
public interface TwoArgIntOperator {
public int op(int a, int b);
}
//elsewhere:
static int method(TwoArgIntOperator operator) {
return operator.op(5, 10);
}
Using your own interface has the advantage that you can have names that more clearly indicate the intent. 使用您自己的界面的优点是您可以使用更清楚地表明意图的名称。
#3楼
There's a public Web-accessible version of the Lambda-enabled Java 8 JavaDocs, linked from http://lambdafaq.org/lambda-resources . 从http://lambdafaq.org/lambda-resources链接到一个支持Lambda的Java 8 JavaDocs的公共Web访问版本。 (This should obviously be a comment on Joachim Sauer's answer, but I can't get into my SO account with the reputation points I need to add a comment.) The lambdafaq site (I maintain it) answers this and a lot of other Java-lambda questions. (这显然应该是对Joachim Sauer的回答的评论,但是我无法获得我需要添加评论的声誉点的SO帐户。)lambdafaq网站(我维护它)回答了这个问题以及许多其他Java -lambda问题。
NB This answer was written before the Java 8 GA documentation became publicly available . 注意:此答案是在Java 8 GA文档公开可用之前编写的。 I've left in place, though, because the Lambda FAQ might still be useful to people learning about features introduced in Java 8. 不过,我仍然留在原地,因为Lambda FAQ对于学习Java 8中引入的功能的人们可能仍然有用。
#4楼
To use Lambda expression you need to either create your own functional interface or use Java functional interface for operation that require two integer and return as value. 要使用Lambda表达式,您需要创建自己的功能接口或将Java功能接口用于需要两个整数并作为值返回的操作。 IntBinaryOperator IntBinaryOperator
Using user defined functional interface 使用用户定义的功能界面
interface TwoArgInterface {
public int operation(int a, int b);
}
public class MyClass {
public static void main(String javalatte[]) {
// this is lambda expression
TwoArgInterface plusOperation = (a, b) -> a + b;
System.out.println("Sum of 10,34 : " + plusOperation.operation(10, 34));
}
}
Using Java functional interface 使用Java功能界面
import java.util.function.IntBinaryOperator;
public class MyClass1 {
static void main(String javalatte[]) {
// this is lambda expression
IntBinaryOperator plusOperation = (a, b) -> a + b;
System.out.println("Sum of 10,34 : " + plusOperation.applyAsInt(10, 34));
}
}
Other example I have created is here 我创建的其他示例在这里
#5楼
For functions that do not have more than 2 parameters, you can pass them without defining your own interface. 对于不超过2个参数的函数,可以在不定义自己的接口的情况下传递它们。 For example, 例如,
class Klass {
static List<String> foo(Integer a, String b) { ... }
}
class MyClass{
static List<String> method(BiFunction<Integer, String, List<String>> fn){
return fn.apply(5, "FooBar");
}
}
List<String> lStr = MyClass.method((a, b) -> Klass.foo((Integer) a, (String) b));
In BiFunction<Integer, String, List<String>>
, Integer
and String
are its parameters, and List<String>
is its return type. 在BiFunction<Integer, String, List<String>>
, Integer
和String
是其参数,而List<String>
是其返回类型。
For a function with only one parameter, you can use Function<T, R>
, where T
is its parameter type, and R
is its return value type. 对于仅具有一个参数的函数,可以使用Function<T, R>
,其中T
是其参数类型,而R
是其返回值类型。 Refer to this page for all the interfaces that are already made available by Java. 有关Java已经提供的所有接口,请参考此页面 。
#6楼
Lambda expression can be passed as a argument.To pass a lambda expression as an argument the type of the parameter (which receives the lambda expression as an argument) must be of functional interface type. 可以将Lambda表达式作为参数传递。要将Lambda表达式作为参数传递,参数的类型(接收lambda表达式作为参数)必须具有功能接口类型。
If there is a functional interface - 如果有功能界面-
interface IMyFunc {
boolean test(int num);
}
And there is a filter method which adds the int in the list only if it is greater than 5. Note here that filter method has funtional interface IMyFunc as one of the parameter. 并且有一个过滤器方法仅在列表中大于5的情况下才将int添加到列表中。请注意,此处的过滤器方法将函数接口IMyFunc作为参数之一。 In that case lambda expression can be passed as an argument for the method parameter. 在这种情况下,可以将lambda表达式作为方法参数的参数传递。
public class LambdaDemo {
public static List<Integer> filter(IMyFunc testNum, List<Integer> listItems) {
List<Integer> result = new ArrayList<Integer>();
for(Integer item: listItems) {
if(testNum.test(item)) {
result.add(item);
}
}
return result;
}
public static void main(String[] args) {
List<Integer> myList = new ArrayList<Integer>();
myList.add(1);
myList.add(4);
myList.add(6);
myList.add(7);
// calling filter method with a lambda expression
// as one of the param
Collection<Integer> values = filter(n -> n > 5, myList);
System.out.println("Filtered values " + values);
}
}