如果您需要 TriFunction,只需执行以下操作:
@FunctionalInterface
interface TriFunction<A,B,C,R> {
R apply(A a, B b, C c);
default <V> TriFunction<A, B, C, V> andThen(
Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (A a, B b, C c) -> after.apply(apply(a, b, c));
}
}
下面的小程序展示了它的使用方法。请记住,结果类型被指定为最后一个泛型类型参数。
public class Main {
public static void main(String[] args) {
BiFunction<Integer, Long, String> bi = (x,y) -> ""+x+","+y;
TriFunction<Boolean, Integer, Long, String> tri = (x,y,z) -> ""+x+","+y+","+z;
System.out.println(bi.apply(1, 2L)); //1,2
System.out.println(tri.apply(false, 1, 2L)); //false,1,2
tri = tri.andThen(s -> "["+s+"]");
System.out.println(tri.apply(true,2,3L)); //[true,2,3]
}
}
我想如果 TriFunction 有实际用途,java.util.*
或者java.lang.*
它会被定义。不过,我永远不会超过 22 个参数;-) 我的意思是,所有允许流式传输集合的新代码都不需要 TriFunction 作为任何方法参数。所以不包括在内。
更新
为了完整起见并遵循另一个答案(与柯里化相关)中的破坏性函数解释,以下是如何在没有额外接口的情况下模拟 TriFunction:
Function<Integer, Function<Integer, UnaryOperator<Integer>>> tri1 = a -> b -> c -> a + b + c;
System.out.println(tri1.apply(1).apply(2).apply(3)); //prints 6
当然,也可以通过其他方式组合功能,例如:
BiFunction<Integer, Integer, UnaryOperator<Integer>> tri2 = (a, b) -> c -> a + b + c;
System.out.println(tri2.apply(1, 2).apply(3)); //prints 6
//partial function can be, of course, extracted this way
UnaryOperator partial = tri2.apply(1,2); //this is partial, eq to c -> 1 + 2 + c;
System.out.println(partial.apply(4)); //prints 7
System.out.println(partial.apply(5)); //prints 8
虽然柯里化对于任何支持 lambda 之外的函数式编程的语言都是很自然的,但 Java 不是以这种方式构建的,虽然可以实现,但代码很难维护,有时也很难阅读。但是,它作为练习非常有用,有时部分函数在您的代码中占有一席之地。