如何将方法作为参数传递?

5
我有一个包含多个方法的类。在另一个类中,我需要编写一个处理输入值的方法。我想将要调用的类的方法传递给该方法。在Java 1.8之后,我们如何实现这一点?
已经有类似的问题了,但是通常假设我们可以使用一个具有单个方法的接口,因此可以使用lambda表达式等。
class MyClass {
    public Object myToString(String a) {
        return new String(a);
    }

    public Object myToString(String a, String b) {
       return new String(a + ", " + b);
    }

    public Object mySum(int a) {
        return new Integer(a);
    }

    public Object mySum(int a, int b) {
        return new Integer(a + b);
    }
}

class Test {
    public Object handleInputs(MyClass myClass, MethodAsParameter theMethod, List<Object> inputs) {
        if (type of inputs are Strings) {
            myClass.myToString(inputs.get(0));
        } else if (.....) {
            myClass.mySum(inputs.get(0));
        }
    }
}

你不是传递方法,而是将值传递给这些方法,并从中获取结果。(在创建包含函数的类的实例之后)。 - Khan Saab
您在handleInputs中没有使用theMethod - fps
3个回答

7
自Java 8开始,您可以使用方法引用(Method reference)。方法引用可以分配给Function<A, B>函数接口变量及其子类。
例如,具有此签名的方法:
class Test {
    public static int DoSomething(String s) {...}
}

可以将其分配给Function<String,Integer>变量,如下所示:

最初的回答

Function<String, Integer> method = Test::DoSomething;

最初的回答
然后被称为:
int result = method.apply("Hello!");

通过对代码进行小的改进,你可以将你的方法作为方法引用并将其作为参数传递给其他函数。最初的回答。

class MyClass {

    public static String myToString(String a, String b) {
        return a + ", " + b;
    }

    //notice the boxing in here
    public static int mySum(int a, int b) {
        return a + b;
    }

    //not kind of an revolutionary function, just for demonstration
    public static<T> T Invoke(BinaryOperator<T> bo, T o1, T o2) {
        return bo.apply(o1, o2);
    }


    public static void main(String[] args) {

        int sum = Invoke(MyClass::mySum, 10, 20);
        String str = Invoke(MyClass::myToString, "a", "b");

        System.out.println(sum);
        System.out.println(str);

}

}


2
我认为你能得到的就是这样的东西:
import java.util.List;
import java.util.Arrays;
import java.util.function.Function;
import java.util.function.BiFunction;

class MyClass {
    public Object myToString(String a) {
        return new String(a);
    }

    public Object myToString(String a, String b) {
       return new String(a + ", " + b);
    }

    public Object mySum(int a) {
        return Integer.valueOf(a);
    }

    public Object mySum(int a, int b) {
        return Integer.valueOf(a + b);
    }
}

public class MethodParams {
    public static Object handleInputs(Function<Object,Object> method, List<Object> inputs) {
        return method.apply(inputs.get(0));
    }

    public static Object handleInputs(BiFunction<Object,Object,Object> method, List<Object> inputs) {
        return method.apply(inputs.get(0), inputs.get(1));
    }    

    public static void main(String args[]) {
        MyClass mc = new MyClass();

        String str = (String)handleInputs((a) -> mc.myToString((String)a), Arrays.asList("string"));
        System.out.println(str); // string

        Integer sum = (Integer)handleInputs((a) -> mc.mySum((int)a), Arrays.asList(1));
        System.out.println(sum); // 1

        Integer sum2 = (Integer)handleInputs((a,b) -> mc.mySum((int)a, (int)b), Arrays.asList(1, 2));
        System.out.println(sum2); // 3
    }
}

虽然不太好,但至少你可以自由选择使用哪种方法。这里演示的代码由于使用了对象而有很多强制转换 - 使用t2dohx演示的通用类型是更好的方法,但离你的问题更远。


0
这是一个简单的例子:
public class TestMain {

    public static void main(String [] args) {
        Long a = 15L, b = 20L;
        Long sum = combineTwoNumbers(a, b, (p1, p2) -> p1 + p2);
        Long product = combineTwoNumbers(a, b, (p1, p2) -> p1 * p2);
        System.out.println("Sum is " + sum);
        System.out.println("Product is " + product);
    }

    public static Long combineTwoNumbers(Long a, Long b, BiFunction <Long, Long, Long> combiner) {
        return combiner.apply(a, b);
    }
}

这里,函数参数是 BiFunction,它接受两个输入参数并返回一个输出。具体来说,它接受两个长整型数,并生成第三个作为结果。方法的名称保持通用,以涵盖可能发生的不同函数的更多实例。在我们的示例中,我们传递了一个求和函数和一个乘积函数,正如您所看到的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接