Java 8: Where is TriFunction (and kin) in java.util.function? Or what is the alternative?

后端 未结 7 1314
臣服心动
臣服心动 2020-11-30 17:46

I see java.util.function.BiFunction, so I can do this:

BiFunction f = (x, y) -> { return 0; };

What if

7条回答
  •  天命终不由人
    2020-11-30 18:14

    If you need TriFunction, just do this:

    @FunctionalInterface
    interface TriFunction {
    
        R apply(A a, B b, C c);
    
        default  TriFunction andThen(
                                    Function after) {
            Objects.requireNonNull(after);
            return (A a, B b, C c) -> after.apply(apply(a, b, c));
        }
    }
    

    Following small program shows how it can be used. Remember that result type is specified as a last generic type parameter.

      public class Main {
    
        public static void main(String[] args) {
            BiFunction bi = (x,y) -> ""+x+","+y;
            TriFunction 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]
        }
      }
    

    I guess if there was practical use for TriFunction in java.util.* or java.lang.* it would have been defined. I would never go beyond 22 arguments, though ;-) What I mean by that, all new code that allows to stream collections never required TriFunction as any of the method parameters. So it was not included.

    UPDATE

    For completeness and following the destructive functions explanation in another answer (related to currying), here is how TriFunction can be emulated without additional interface:

    Function>> tri1 = a -> b -> c -> a + b + c;
    System.out.println(tri1.apply(1).apply(2).apply(3)); //prints 6
    

    Of course, it is possible to combine functions in other ways, e.g.:

    BiFunction> 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
    

    While currying would be natural to any language that supports functional programming beyond lambdas, Java is not built this way and, while achievable, the code is hard to maintain, and sometimes read. However, it is very helpful as an exercise, and sometimes partial functions have a rightful place in your code.

提交回复
热议问题