有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

有没有一种简单的方法可以从Java中相同接口的多个实现中创建级联函数?

有没有一种简单的方法来获得级联实现

public interface SomeInterface {
    void call(SomeClassA a, SomeClassB b, SomeClassC c);
}
SomeInterface imp1;
SomeInterface imp2;
SomeInterface imp3;

public SomeInterface getFunction() {
    return (a, b, c) -> {
        imp1.call(a, b, c);
        imp2.call(a, b, c);
        imp3.call(a, b, c);
    }
}

我想要的是:

public SomeInterface getFunction() {
    return SomeUtils.cascade(imp1, imp2, imp3);
}

有任何SomeUtils等价物吗


编辑/添加: 我用返回值重写它的更一般的方式,可能是这样的:

@FunctionalInterface
public interface TriFunction<P1, P2, P3, R> {
    R call(P1 p1, P2 p2, P3 p3);
}
public class LambdaUtils {
    public static <P1, P2, P3, R> TriFunction<P1, P2, P3, R> cascade(
            BinaryOperator<R> reducer,
            TriFunction<P1, P2, P3, R>... lambdas ) {
        // assumes lambda.length > 0 or should check it
        return (a, b, c) ->
            Arrays.stream(lambdas)
                    .map( l -> l.call(a, b, c) )
                    .reduce( reducer ).get();
    }
}

使用LambdaUtils的示例如下:

public interface SomeInterface {
    Object call(Object a, Object b, Object c);
}
...
    public void hoge() {
        SomeInterface i = (a, b, c) -> a;
        SomeInterface j = (a, b, c) -> b;
        SomeInterface k = (a, b, c) -> c;
        SomeInterface all = LambdaUtils.cascade(
                (a, b) -> (b),
                i::call, j::call, k::call )::call;
    }
...

LambdaUtils.cascade()有几个问题:

  • 这仅适用于具有3个参数的lambda
  • 这仅适用于返回R的lambda,而不是void(或者如果您在上面重写以接受void类型的函数,则它不能应用于返回的结果版本)

那么,它是否可以改写为:

  • 接受任意数量的参数
  • 不在乎退货类型(R/void)

因为我认为这是一个通用的东西,所以我在一些OSS库中寻找这个功能,比如ApacheCommons

谢谢你的建议


共 (1) 个答案

  1. # 1 楼答案

    我在这里没有看到级联,因为1次调用的结果没有被用作下一次调用的输入。您所做的,可以通过简单的for循环或流来完成

    public static SomeInterface forEach(SomeInterface... implsArr){
        List<SomeInterface> impls = Arrays.asList(implsArr);
        return (a,b,c)-> impls.forEach(impl->impl.call(a,b,c));
        //or
        return (a,b,c)->{
            for(SomeInterface impl:implsArr){
                impl.call(a,b,c);
            }
        };
    }
    

    然后它可以用作

    SomeInterface allInOne=forEach(imp1, imp2, imp3 ... impN);
    allInOne.call(a,b,c);