在Java8中,如何定义一个将lambda作为参数的方法?

在Java8中,如何定义一个将lambda作为参数的方法?,java,lambda,java-8,Java,Lambda,Java 8,在Java8中,方法可以创建为Lambda表达式,并且可以通过引用传递(只需做一点工作)。在线上有很多创建lambda并与方法一起使用的示例,但是没有关于如何创建以lambda为参数的方法的示例。它的语法是什么 MyClass.method((a, b) -> a+b); class MyClass{ //How do I define this method? static int method(Lambda l){ return l(5, 10); } } l

在Java8中,方法可以创建为Lambda表达式,并且可以通过引用传递(只需做一点工作)。在线上有很多创建lambda并与方法一起使用的示例,但是没有关于如何创建以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纯粹是一个调用站点构造:lambda的接收者不需要知道涉及到lambda,而是接受具有适当方法的接口

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

为此,Java8在中提供了一组常用的接口类型(感谢提供了关于JavaDoc的提示)

对于这个特定的用例,您可以这样编写
方法

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);
}
但您也可以定义自己的接口,并像这样使用它:

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);
}

使用您自己的接口的优点是,您可以使用更清楚地指示意图的名称。

有一个支持Lambda的Java 8 JavaDocs的公共Web可访问版本,链接自。(这显然应该是对Joachim Sauer的回答的评论,但我无法进入我的SO帐户,因为我需要添加评论的信誉点。)lambdafaq网站(我维护它)回答了这一点和许多其他Java lambda问题


注意:这个答案是在Java8GA文档发布之前写的。尽管如此,我还是留下来了,因为对于学习Java 8中引入的功能的人来说,可能仍然很有用。

要使用Lambda表达式,您需要创建自己的函数接口,或者使用Java函数接口进行需要两个整数并作为值返回的操作

使用用户定义的功能界面

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));

    }
}
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));

    }
}
使用Java功能接口

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));

    }
}
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));

    }
}

对于参数不超过2个的函数,可以在不定义自己接口的情况下传递它们。例如,

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));
Klass类{
静态列表foo(整数a,字符串b){…}
}
类MyClass{
静态列表法(双功能fn){
返回fn.应用(5,“FooBar”);
}
}
List lStr=MyClass.method((a,b)->Klass.foo((整数)a,(字符串)b));
BiFunction
中,
Integer
String
是它的参数,
List
是它的返回类型


对于只有一个参数的函数,可以使用
函数
,其中
T
是其参数类型,
R
是其返回值类型。关于Java已经提供的所有接口,请参阅本节

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

如果有功能接口——

interface IMyFunc {
   boolean test(int num);
}
还有一种过滤方法,它只在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);
    }
}
公共类LambdaDemo{
公共静态列表筛选器(IMyFunc testNum,列表项){
列表结果=新建ArrayList();
对于(整数项:listItems){
if(testNum.test(项目)){
结果.添加(项目);
}
}
返回结果;
}
公共静态void main(字符串[]args){
List myList=new ArrayList();
添加(1);
添加(4);
添加(6);
增加(7);
//使用lambda表达式调用筛选器方法
//作为其中的一员
集合值=过滤器(n->n>5,myList);
System.out.println(“过滤值”+值);
}
}

使用lambda作为参数具有灵活性。它支持java中的函数式编程。基本语法是

参数->方法\u正文

下面是一种方法,您可以定义一个以函数接口(使用lambda)为参数的方法。 A.如果希望定义在函数接口内声明的方法, 比如说,函数接口作为从
main()

FInterface fi=(x)->{return 0;}

函数匿名或匿名(fi)

在上面可以看到,lambda表达式如何被接口替换

上面解释了lambda表达式的一个特殊用法,还有更多。 裁判
好吧,那很容易。lambda表达式的目的是实现函数接口。它是只有一种方法的接口

无论如何,如果你想实现你自己的功能接口,那就去做吧。举个简单的例子:

public interface MyFunctionalInterface {
    String makeIt(String s);
}
让我们创建一个类,在其中我们将创建一个方法,该方法接受MyFunctionInterface类型:

interface Callback {
    void call();
}
您应该做的最后一件事是将MyFunctionInterface的实现传递给我们定义的方法:

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不是一个对象,而是一个功能接口。 使用@FunctionalInterface作为注释,可以定义尽可能多的功能接口

@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函数的定义从addition更改为任何其他定义,但您的参数限制为2。

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

Import java.util.function.Consumer
公共班机{
公共图书馆
method(new Callback() {
    @Override
    public void call() {
        // Classic interface implementation, lot of useless boilerplate code.
        // method() is done, do whatever you want here.
    }
});
public int add(int a,int b);  
Function<Integer, Integer> f1 = num->(num*2+1);
System.out.println(f1.apply(10));

Predicate<Integer> f2= num->(num > 10);
System.out.println(f2.test(10));
System.out.println(f2.test(11));

Supplier<Integer> f3= ()-> 100;
System.out.println(f3.get());
import static org.util.function.Functions.*;

public class Test {

    public static void main(String[] args)
    {
        Test.invoke((a, b) -> a + b);       
    }

    public static void invoke(Func2<Integer, Integer, Integer> func)
    {
        System.out.println(func.apply(5, 6));
    }
}
package org.util.function;

public interface Functions {

    //Actions:
    public interface Action {
        public void apply();
    }

    public interface Action1<T1> {
        public void apply(T1 arg1);
    }

    public interface Action2<T1, T2> {
        public void apply(T1 arg1, T2 arg2);
    }

    public interface Action3<T1, T2, T3> {
        public void apply(T1 arg1, T2 arg2, T3 arg3);
    }

    public interface Action4<T1, T2, T3, T4> {
        public void apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
    }

    public interface Action5<T1, T2, T3, T4, T5> {
        public void apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
    }

    public interface Action6<T1, T2, T3, T4, T5, T6> {
        public void apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
    }

    public interface Action7<T1, T2, T3, T4, T5, T6, T7> {
        public void apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
    }

    public interface Action8<T1, T2, T3, T4, T5, T6, T7, T8> {
        public void apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
    }

    //Functions:
    public interface Func<TResult> {
        public TResult apply();
    }

    public interface Func1<T1, TResult> {
        public TResult apply(T1 arg1);
    }

    public interface Func2<T1, T2, TResult> {
        public TResult apply(T1 arg1, T2 arg2);
    }

    public interface Func3<T1, T2, T3, TResult> {
        public TResult apply(T1 arg1, T2 arg2, T3 arg3);
    }

    public interface Func4<T1, T2, T3, T4, TResult> {
        public TResult apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
    }

    public interface Func5<T1, T2, T3, T4, T5, TResult> {
        public TResult apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
    }

    public interface Func6<T1, T2, T3, T4, T5, T6, TResult> {
        public TResult apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
    }

    public interface Func7<T1, T2, T3, T4, T5, T6, T7, TResult> {
        public TResult apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
    }

    public interface Func8<T1, T2, T3, T4, T5, T6, T7, T8, TResult> {
        public TResult apply(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
    }
}