当前位置: 首页 > 知识库问答 >
问题:

作为方法参数的功能接口

卫梓
2023-03-14

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

  • 将通用数组作为输入处理,检查其最小长度是否为4
  • 处理我的功能界面的任何实例
  • 处理lambda表达式的任何实例,该表达式接受一个参数,但不返回任何内容
  • 应用于函数接口实例的结果(这里我想我必须使用使用者)

以前从未使用过函数接口,有人能解释一下我应该如何将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个答案

华良平
2023-03-14

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

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

但是,正如您很容易注意到的那样,解决方案不能真正扩展到包含4个以上的元素。不过不用太担心,JDK的开发人员已经注意到了这种简化,并提供了一种方法,可以在每次使用两个参数的输入流上连续操作。所有这些都指导您使用数组。流和进一步的流。reduce对提供的二进制运算符执行求值。这将您的示例简化为

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

在这一点上,您必须小心使用运算符,因为它遵守以下属性-

用于组合两个值的关联、无干扰、无状态函数

杨经武
2023-03-14

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

具体回答这个问题,您可以像任何其他类型一样传递功能接口。

private static void printAddAndConcatenate(MyFunctionalInterface<Integer> add, MyFunctionalInterface<String> concatenate) {
    System.out.println(add.doOperation(1, 1, 1, 1));
    System.out.println(concatenate.doOperation("Hel", "lo ", "Wo", "rld"));
}

public static void main(String[] args) {
    printAddAndConcatenate(Lambdas.ADD, Lambdas.CONCATENATE);
}
 类似资料:
  • 问题内容: 我几天前接受采访时,被问到这样的问题。 问:反向链接列表。给出以下代码: 我很困惑,因为我不知道接口对象可以用作方法参数。面试官解释了一下,但我仍然不确定。有人可以启发我吗? 问题答案: 实际上,这是使用接口的最常见和最有用的方法之一。该接口定义了一个契约,您的代码可以与实现该接口的任何类一起使用,而无需了解具体的类- 它甚至可以与编写代码时尚不存在的类一起使用。 Java标准API中

  • 问题内容: 我不知道为什么此代码在PHP中不起作用? 看来它没有违反任何OOP规则,但是为什么它给我一个错误? 问题答案: 它 确实 违反了SOLID规则。您声明接受一个类型的参数,但子级接受一个类型的参数。即使是的子类型,它仍然是不同的类型。 当上课的时候,上课也是正确的。但是接受一个,但是不接受一个。因此,据推测,但不接受type参数。这打破了Liskov替代原则。您不能在子接口,周期中更改参

  • 问题内容: 我正在寻找一种通过引用传递方法的方法。我知道Java不会将方法作为参数传递,但是,我想找到一种替代方法。 有人告诉我接口是将方法作为参数传递的替代方法,但我不了解接口如何通过引用充当方法。如果我理解正确,那么接口就是一组未定义的抽象方法。我不想发送每次都需要定义的接口,因为几种不同的方法可以使用相同的参数调用同一方法。 我要完成的工作与此类似: 调用如: 问题答案: 编辑:从Java

  • 目前正在学习Java 8 lambda表达式和方法引用。 我想把一个没有参数和返回值的方法作为参数传递给另一个方法。我就是这样做的: 我知道如

  • 问题内容: 在Java 8中,只有一个抽象方法的抽象类不是功能接口(JSR 335 )。 这是一个功能接口: 但这不是: 因此,我不能将抽象类用作lambda表达式和方法引用的目标。 编译错误为:。 语言设计者为什么要施加此限制? 问题答案: 自Lambda项目成立以来,这一直是一个重要的话题,并且引起了很多思考。Java语言首席架构师Brian Goetz强烈支持将lambda视为 功能 而非

  • 在java 8中,只有一个抽象方法的抽象类不是函数接口(JSR 335)。 这个是一个功能接口: 但这个抽象类不是: 因此,我不能将抽象类用作lambda表达式和方法引用的目标。 编译错误为:。 为什么语言设计者会施加这种限制?