java - 是否可以递归链接通用函数?

标签 java

假设我有以下代码:

var output = chain(
        0,
        n -> n + "hi",
        n -> n,
        n -> n + 1,
        n -> n.equals("0hi1")
);

如何使该方法接受任意数量的函数?

我知道我能做到:

public static <A, B, C, D, E> E chain(
        A val,
        Function<? super A, ? extends B> f1,
        Function<? super B, ? extends C> f2,
        Function<? super C, ? extends D> f3,
        Function<? super D, ? extends E> f4
) {
    return f4.apply(f3.apply(f2.apply(f1.apply(val))));
}

但这严重限制了输入量。

我可以编写一些递归函数吗?也许可以接受可变参数?

类似这样的事情:

public static OutputType chain(
        InputType val,
        Function<?, ?>... functions
) {
    var nextInput = functions[0].apply(val);
    if (functions.length == 1) return nextInput;
    var tail = Arrays.copyOfRange(functions, 1, functions.length);
    return chain(nextInput, tail);
}

我知道我可以创建一个 monad,或者使用流,或者使用可选的链式转换:

var output = Optional
        .of(0)
        .map(n -> n + "hi")
        .map(n -> n)
        .map(n -> n + 1)
        .map(n -> n.equals("0hi1"))
        .get();

但我特别不想这样做。我想实现第一个代码块中可见的样式。

最佳答案

假设调用中的所有函数都具有相同的类型,那么可以在方法上使用简单的泛型类型来完成:

public static <T> T chain(
        T val,
        Function<T, T>... functions
) {
    if (functions.length == 0) return val;
    var nextInput = functions[0].apply(val);
    if (functions.length == 1) return nextInput;
    var tail = Arrays.copyOfRange(functions, 1, functions.length);
    return chain(nextInput, tail);
}

还可以进行其他改进(例如,仅使用索引计数器进行递归以避免数组复制,或者不进行递归)。要格外小心边界条件,例如传递一个空调用。

使用此功能,您可以使用任何类型的输入,并且这些函数将需要在相同的输入和输出类型上进行操作。

关于java - 是否可以递归链接通用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77061671/

相关文章:

java - 执行 maven 3 - 何时使用 maven enforcer 插件?什么时候使用 pom 先决条件元素?

Java 8 将 String of int 转换为 List<Integer>

java - 是否可以解决不使用更广泛的异常“System.Exception”的问题?

java - 使用 itemReader Spring Batch 读取 XML 中节点的属性

java - 按第一个单词对 ArrayList 进行排序

java - 栈为空时pop抛出什么异常

java - 如何仅包含要由 Jackson 序列化的对象的某些属性和字段?

Java重复不同的唯一数组值

java - 接口(interface)和参数问题

java - Selenium RemoteWebDriver FileDetector Java