Java 8 Functions - compose and andThen

function, functional-programming, java

Solution

While `a.andThen(b)` is equivalent to `b.compose(a)`, there’s a practical difference at the use side, when only one of these two functions is an already existing function.

Suppose, you have the already existing function

Function<Integer, String> iToHex = i -> "'" + Integer.toHexString(i) + "'";

and then, you want to chain a string transformation, e.g.

Function<Integer, String> itoUpperHex = iToHex.andThen(String::toUpperCase);

`andThen` obviously is much more convenient, compared to

Function<Integer,String> itoUpperHex
                       = ((Function<String,String>)String::toUpperCase).compose(iToHex);

On the other hand, if your already existing function is

Function<String, String> quote = s -> "'" + s + "'";

and you want to create the quoted hex function,

Function<Integer, String> iToHex = quote.compose(Integer::toHexString);

will be much more convenient, compared to

Function<Integer, String> iToHex = ((Function<Integer, String>) Integer::toHexString).andThen(quote);

So the decision for either method depends on which function already exists. If both are already existing functions, it doesn’t matter which method you use (unless you suspect that one of these functions might have overridden these methods to perform a more efficient composition). If you have no existing function as starting point, there is no reason to use any of these methods, as you can write the composed expression as a single lambda expression.

Problem

I find my Java knowledge out-of-date with Java 8, and there are many new language features I am trying to learn. One of them is Functions, specifically the `compose` and `andThen` methods. I have written a trivial experiment to test the reversibility of `compose` and `andThen`: ``` /** Wraps a value */ public class Wrap<T> { private final T value; private Wrap(T value) { this.value = value; } public static <T> Wrap<T> of(T value) { return new Wrap<>(value); } } static void functions() { Function<Integer,String> itos = i->"'"+i+"'"; Function<String,Wrap<String>> stow = s->Wrap.of(s); Function<Integer,Wrap<String>> itow = itos.andThen(stow); Function<Integer,Wrap<String>> itow2 = stow.compose(itos); System.out.println(itow.apply(3)); System.out.println(itow2.apply(3)); } ``` In the above code, as expected, the 2 Functions `itow` and `itow2` seem to be equivalent. But are they actually equivalent? Do the have the same result somewhat by accident in this case? The thought occurs that both `compose` and `andThen` methods exist for a reason, and that Functions or BiFunctions might not always be reversible in this way. Can you think of any cases where the reversibility would not apply?

Original source