java - Java lambda 可以将方法绑定(bind)到它们的参数吗?

标签 java lambda function-pointers function-binding

这里讨论如何使用 lambda 将方法作为参数传递:
Java Pass Method as Parameter

在其他语言中,即 C++,可以使用 Lambdas 将函数绑定(bind)到它的参数 - 此处讨论:
Bind Vs Lambda?

在 Java 中,是否可以使用 lambdas 绑定(bind)方法?

如果是这样,您将如何实现?

编辑>>>>

根据要求,我通常尝试做的一个例子:

请注意,这里有伪代码。

public class DataView {

    private static ArrayList<Float> rectData = new ArrayList<Float>();
    private static ArrayList<Float> textData = new ArrayList<Float>();

    DataView(){

        //Pseudo Code:
        boundFunction mybind  = boundFunction(functionA, 5, 10);
        boundFunction mybind2 = boundFunction(functionB, 10, 12);

        iter(mybind);
        iter(mybind2);

    }

    //Method with pseudo parameter
    private void iter(functionSignature){
        for(Float i : textData){

            //Pseudo call to pseudo parameter
            functionSignature();

        }
    }

    private void functionA(int a, int b){
        //dostuff

    }

    private void functionB(int a, int b){
        //do other stuff

    }

切记,我不是在寻找“实现此功能的另一种方法”——此示例是为了说明我希望将函数用作参数并将参数绑定(bind)到这些函数的一般方法。

编辑>>>

尝试使用匿名类:

public class DataView {

    private class Bound{ 
        public void run(){}

    }

    private static ArrayList<Float> rectData = new ArrayList<Float>();
    private static ArrayList<Float> textData = new ArrayList<Float>();

    DataView(){

        Bound mybind = new Bound(){
            public void run(){
                functionA(5,10);
            }
        };

        Bound mybind2 = new Bound(){
            public void run(){
                functionB(5,10);
            }
        };

        iter(mybind);
        iter(mybind2);

    }

    private void iter(Bound function){
        for(Float i : textData){

            function.run();

        }
    }

    private void functionA(int a, int b){
        //dostuff

    }

    private void functionB(int a, int b){
        //do other stuff

    }
}

最佳答案

如其他答案所述,Java 需要一个实际的功能接口(interface)类型来表示一个函数。这也适用于绑定(bind)操作,它甚至需要两个这样的接口(interface),一个代表未绑定(bind)的函数,另一个代表绑定(bind)的函数:

public class DataView {
    interface NoArgFunction {
        void func();
    }
    interface TwoIntFunction {
        void func(int a, int b);
    }
    static NoArgFunction bind(TwoIntFunction f, int first, int second) {
        return () -> f.func(first, second);
    }

    private static ArrayList<Float> rectData = new ArrayList<Float>();
    private static ArrayList<Float> textData = new ArrayList<Float>();

    DataView(){
        NoArgFunction mybind  = bind(this::functionA, 5, 10);
        NoArgFunction mybind2 = bind(this::functionB, 10, 12);

        iter(mybind);
        iter(mybind2);
    }
    private void iter(NoArgFunction noArg){
        for(Float i : textData){
            noArg.func();
        }
    }
    private void functionA(int a, int b){
        //dostuff
    }
    private void functionB(int a, int b){
        //do other stuff
    }
}

一个有趣的事实是,在字节码级别上,可以在没有中间步骤的情况下将方法与参数结合起来,这正是 lambda 表达式 () -> f.func( first, second),它被编译成一个包含 lambda 主体的合成方法,并有两个参数 firstsecond 将在运行时用于构造NoArgFunction 实例绑定(bind)了 firstsecond 的当前值。

但是你不能在 Java 源代码中使用它。现有方法唯一支持的绑定(bind)是在方法引用 this::functionAthis::functionB 中看到的绑定(bind),它们都绑定(bind)当前的 this 方法 functionAfunctionB 的实例。好吧,使用像
这样的 lambda 表达式 NoArgFunction mybind = () -> functionA(5, 10); 首先没有 bind 方法 确实 缩短了过程……

因此,最重要的是,试图与试图为不受内在支持的功能建模的语言作斗争没有多大意义。使用 lambda 表达式而不是绑定(bind),以及为此目的预定义的目标类型使代码更加简单:

public class DataView {
    private static ArrayList<Float> rectData = new ArrayList<Float>();
    private static ArrayList<Float> textData = new ArrayList<Float>();

    DataView(){
        iter(x -> functionA(5, 10));
        iter(x -> functionB(10, 12));
    }
    private void iter(Consumer<Float> function){
        textData.forEach(function);
    }
    private void functionA(int a, int b){
        //dostuff
    }
    private void functionB(int a, int b){
        //do other stuff
    }
}

关于java - Java lambda 可以将方法绑定(bind)到它们的参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38487755/

相关文章:

c++ - 具有函数指针和可变参数模板的 CUDA 内核

参数数量未知的 C++ 函数指针

java - Google JSON,反序列化类并正确设置类字段值

java - 如何在 Activity 的 spring 事务中将数据刷新到数据库中?

c++ - Lambda 构造性能和静态 lambda?

c# - IndexOf 与 Linq,接受 lambda 表达式

java - Lambda 表达式中的这段 Java 代码是什么意思?

c - 如何初始化函数指针数组?

java - 通过 JDBC URL 使用 TestContainers DB 但与 @Rule 一起使用时出错

java - Unity 中的回调监听器 - 如何从 Android 中的 UnityPlayerActivity 调用脚本文件方法