Search code examples
javafunctionlambdamethod-reference

Why function composing not available in IntFunction


I was reading the function composition section from Chap-3 Modern Java in action.

I am unable to understand why I can't compose IntFunctions. Am I making a silly mistake or is there any design decision behind this ?

Here is my code with error in comments

package mja;

import java.util.function.Function;
import java.util.function.IntFunction;

public class AppTest2 {
    public static void main(String[] args) {
        
        IntFunction<Integer> plusOne = x -> x+1;
        IntFunction<Integer> square = x -> (int) Math.pow(x,2);
        
        // Compiler can't find method andThen in IntFunction and not allowing to compile
        IntFunction<Integer> incrementThenSquare = plusOne.andThen(square); 
        int result = incrementThenSquare.apply(1);

        Function<Integer, Integer> plusOne2 = x -> x + 1;
        Function<Integer, Integer> square2 = x -> (int) Math.pow(x,2);
        
        //Below works perfectly
        Function<Integer, Integer> incrementThenSquare2 = plusOne2.andThen(square2);
        int result2 = incrementThenSquare2.apply(1);
    }
}

Solution

  • Well, in your example, using IntFunction<Integer> is not really an optimal choice, and this is probably the reason why you're stuck.

    When trying to work on a function that takes an int and returns an int, you want to use IntUnaryOperator which has the method andThen(IntUnaryOperator) you're looking for.

    The reason why it has not been implemented in IntFunction<R> is that you can't be sure your function will return the input necessary for the next IntFunction<R> which is an int of course.

    Your case is straightforward but imagine having a IntFunction<List<String>> instead, you can't chain the functions because IntFunction<R> does not accept a List<String> as an input.


    Here is your corrected example

    IntUnaryOperator plusOne = x -> x + 1;
    IntUnaryOperator square = x -> (int) Math.pow(x, 2);
    
    IntUnaryOperator incrementThenSquare = plusOne.andThen(square);
    int result = incrementThenSquare.applyAsInt(1);
    
    System.out.println("result = " + result); // result = 4