java - 功能接口作为方法参数
问题描述
在编写了我自己的通用函数接口并将其与 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;
}
解决方案
在最简单的形式中,您可以将函数转换直接表示为:
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 的开发人员已经处理了这种简化,并提供了一种方法,可以对一次采用两个参数的输入流进行连续操作。所有这些都将引导您使用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));
}
}
关于这一点,您必须小心使用运算符,例如它遵守以下属性 -
用于组合两个值的关联、非干扰、无状态函数
推荐阅读
- shell - 脚本是 shell 执行后 Jenkins 作业失败运行良好
- python - 如何从 jupyter notebook 访问浏览器本地存储?
- node.js - 使用 Webpack 打包 nodeJS CLI App
- javascript - Javascript - 多行 SQL 格式化
- flutter - 用户未在 Firebase Flutter 中退出
- java - 将反应式存储库与正常的同步/命令式代码混合......如何让事务工作?
- .net - 如何在我的 API/应用程序文件夹之外返回实体的 ID?
- oracle - '[^~]+' 有什么作用?
- python - 如何在具有特定条件的数据框中添加值
- ffmpeg - ffmpeg 无法提取视频结尾附近的帧