在编写了自己的通用功能接口并将其用于lambdas之后,我必须在一种新方法中使用它:
以前从未使用过函数接口,有人能解释一下我应该如何将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;
}
在最简单的形式中,可以将函数转换直接表示为:
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));
}
}
在这一点上,您必须小心使用运算符,因为它遵守以下属性-
用于组合两个值的关联、无干扰、无状态函数
有人能解释一下我应该如何传递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表达式和方法引用的目标。 编译错误为:。 为什么语言设计者会施加这种限制?