功能接口作为方法参数

时间:2020-03-31 15:00:42

标签: java lambda functional-interface

在编写了自己的通用功能接口并将其与lambda结合使用之后,我必须在一种新方法中使用它:

  • 将通用数组作为输入处理,并检查其最小长度为4
  • 处理我的功能接口的任何实例
  • 处理lambda表达式的任何实例,该实例带有一个参数且不返回任何内容
  • 应用于您的功能接口实例的结果(在这里我想我必须使用Consumer)。

以前从未使用过功能接口,有人可以解释一下我应该如何将2个功能接口作为方法参数进行传递吗?

例如通话:

applyTransformations(new Integer[]{1,2,3,4}, add, printer);
@FunctionalInterface
public interface MyFunctionalInterface<T> {
    public T doOperation(T param1, T param2, T param3, T param4);
}
public class Lambdas {
    MyFunctionalInterface<Integer> add = (i1, i2, i3, i4) -> i1 + i2 + i3 + i4;
    MyFunctionalInterface<Integer> multiply = (i1, i2, i3, i4) -> i1 * i2 * i3 * i4;
    MyFunctionalInterface<String> concatenate = (s1, s2, s3, s4) -> s1 + s2 + s3 + s4;
    MyFunctionalInterface<String> concatenateWithSpacesBetween = (s1, s2, s3, s4) -> s1 + " " + s2 + " " + s3 + " " + s4;
}

2 个答案:

答案 0 :(得分:3)

有人可以解释一下我应该如何传递2个函数接口作为方法参数吗?

专门回答这个问题,您可以传递任何其他类型的功能接口。

if (sqlite3_exec(this->db, this->SQL_SELECT_READINGS_QUERY, 
    +[](void* instance, int x, char** y, char** z) {
        return static_cast<dataSend_task*>(instance)->callback(x, y, z);
    },
    this,
    &err))
{
    /* whatever */
}

答案 1 :(得分:2)

在最简单的形式中,您可以将函数转换直接表示为:

static class Lambdas {
    static MyFunctionalInterface<Integer> add = (i1, i2, i3, i4) -> i1 + i2 + i3 + i4;
    static MyFunctionalInterface<Integer> multiply = (i1, i2, i3, i4) -> i1 * i2 * i3 * i4;
    static MyFunctionalInterface<String> concatenate = (s1, s2, s3, s4) -> s1 + s2 + s3 + s4;
    static MyFunctionalInterface<String> concatenateWithSpacesBetween = (s1, s2, s3, s4) -> s1 + " " + s2 + " " + s3 + " " + s4;

    public static void main(String[] args) {
        PrintStream printer = System.out;
        applyTransformations(new Integer[]{1, 2, 3, 4}, add, printer);
        applyTransformations(new Integer[]{2, 3, 4, 5}, multiply, printer);
        applyTransformations(new String[]{"one", "day", "or", "another"}, concatenate, printer);
        applyTransformations(new String[]{"yet", "another", "way", "forward"}, concatenateWithSpacesBetween, printer);
    }

    static <T> void applyTransformations(T[] input, MyFunctionalInterface<T> functionalInterface, PrintStream printer) {
        printer.println(functionalInterface.doOperation(input[0], input[1], input[2], input[3]));
    }
}

但是您会很容易注意到,该解决方案实际上不能扩展为包含四个以上的元素。不过,不必担心,JDK的开发人员已经采取了这种简化措施,并提供了一种方法,使它一次输入两个参数即可连续处理输入流。所有这些都将指导您使用Arrays.stream以及进一步的Stream.reduce,它对提供的BinaryOperator进行评估。这将您的示例简化为

static class Lambdas {
    public static void main(String[] args) {
        PrintStream printer = System.out;
        applyTransformations(new Integer[]{1, 2, 3, 4}, Integer::sum, printer);
        applyTransformations(new Integer[]{2, 3, 4, 5}, (a, b) -> a * b, printer);
        applyTransformations(new String[]{"one", "day", "or", "another"}, String::concat, printer);
        applyTransformations(new String[]{"yet", "another", "way", "forward"}, (a, b) -> a + " " + b, printer);
    }

    static <T> void applyTransformations(T[] input, BinaryOperator<T> binaryOperator, PrintStream printer) {
        printer.println(Arrays.stream(input).reduce(binaryOperator));
    }
}

请注意,您必须小心使用运算符,例如它遵循以下属性-

用于组合两个对象的关联,无干扰,无状态功能 值