在Java 8中,方法可以创建为Lambda表达式,并且可以通过引用传递(在底层做一些工作)。网上有很多创建lambdas并将其与方法一起使用的示例,但没有示例说明如何创建以lambda作为参数的方法。它的语法是什么?

MyClass.method((a, b) -> a+b);


class MyClass{
  //How do I define this method?
  static int method(Lambda l){
    return l(5, 10);
  }
}

当前回答

这很简单。lambda表达式的目的是实现函数接口。它是只有一个方法的接口。这里有一篇关于预定义和遗留功能接口的很棒的文章。

不管怎样,如果你想实现你自己的功能接口,那就做吧。举个简单的例子:

public interface MyFunctionalInterface {
    String makeIt(String s);
}

所以让我们创建一个类,在这里我们将创建一个方法,它接受MyFunctionalInterface的类型:

public class Main {

    static void printIt(String s, MyFunctionalInterface f) {
        System.out.println(f.makeIt(s));
    }

    public static void main(String[] args) {

    }
}

你应该做的最后一件事是将MyFunctionalInterface的实现传递给我们已经定义的方法:

public class Main {

    static void printIt(String s, MyFunctionalInterface f) {
        System.out.println(f.makeIt(s));
    }

    public static void main(String[] args) {
        printIt("Java", s -> s + " is Awesome");
    }
}

就是这样!

其他回答

这很简单。lambda表达式的目的是实现函数接口。它是只有一个方法的接口。这里有一篇关于预定义和遗留功能接口的很棒的文章。

不管怎样,如果你想实现你自己的功能接口,那就做吧。举个简单的例子:

public interface MyFunctionalInterface {
    String makeIt(String s);
}

所以让我们创建一个类,在这里我们将创建一个方法,它接受MyFunctionalInterface的类型:

public class Main {

    static void printIt(String s, MyFunctionalInterface f) {
        System.out.println(f.makeIt(s));
    }

    public static void main(String[] args) {

    }
}

你应该做的最后一件事是将MyFunctionalInterface的实现传递给我们已经定义的方法:

public class Main {

    static void printIt(String s, MyFunctionalInterface f) {
        System.out.println(f.makeIt(s));
    }

    public static void main(String[] args) {
        printIt("Java", s -> s + " is Awesome");
    }
}

就是这样!

Lambda表达式可以作为参数传递。要将lambda表达式作为参数传递,形参的类型(接收lambda表达式作为参数)必须为函数接口类型。

如果有功能接口-

interface IMyFunc {
   boolean test(int num);
}

还有一个filter方法,它只在int值大于5时才将int值添加到列表中。这里注意,filter方法有函数接口IMyFunc作为参数之一。在这种情况下,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);
    }
}

Lambda不是一个对象,而是一个功能接口。 使用@FuntionalInterface作为注释,可以定义尽可能多的功能接口

@FuntionalInterface
public interface SumLambdaExpression {
     public int do(int a, int b);
}

public class MyClass {
     public static void main(String [] args) {
          SumLambdaExpression s = (a,b)->a+b;
          lambdaArgFunction(s);
     }

     public static void lambdaArgFunction(SumLambdaExpression s) {
          System.out.println("Output : "+s.do(2,5));
     }
}

输出将如下所示

Output : 7

Lambda表达式的基本概念是定义自己的逻辑,但已经定义了参数。因此,在上面的代码中,您可以将do函数的定义从加法更改为任何其他定义,但参数限制为2。

Lambdas纯粹是一个调用站点构造:lambda的接收方不需要知道涉及到lambda,而是接受具有适当方法的Interface。

换句话说,您定义或使用一个函数接口(即具有单一方法的接口),该接口接受并返回您想要的内容。

自Java 8以来,Java .util.function中有一组常用的接口类型。

对于这个特定的用例,有java.util.function.IntBinaryOperator和一个int applyAsInt(int left, int right)方法,所以你可以这样写你的方法:

static int method(IntBinaryOperator op){
    return op.applyAsInt(5, 10);
}

但你也可以定义自己的接口,并像这样使用它:

public interface TwoArgIntOperator {
    public int op(int a, int b);
}

//elsewhere:
static int method(TwoArgIntOperator operator) {
    return operator.op(5, 10);
}

然后调用以lambda作为参数的方法:

public static void main(String[] args) {
    TwoArgIntOperator addTwoInts = (a, b) -> a + b;
    int result = method(addTwoInts);
    System.out.println("Result: " + result);
}

使用您自己的接口的好处是您可以使用更清楚地表明意图的名称。

对于任何在谷歌上搜索这个的人来说,一个好方法是使用java.util.function. bicconsumer。 例:

Import java.util.function.Consumer
public Class Main {
    public static void runLambda(BiConsumer<Integer, Integer> lambda) {
        lambda.accept(102, 54)
    }

    public static void main(String[] args) {
        runLambda((int1, int2) -> System.out.println(int1 + " + " + int2 + " = " + (int1 + int2)));
    }

打印结果将是:166