Java8 method reference used as Function object to combine functions

You should be able to achieve what you want inline by using casts:

Stream.of("ciao", "hola", "hello")
      .map(((Function<String, Integer>) String::length).andThen(n -> n * 2))

There are only 'type hints' for the compiler, so they don't actually 'cast' the object and don't have the overhead of an actual cast.


Alternatively, you can use a local variable for readability:

Function<String, Integer> fun = String::length

Stream.of("ciao", "hola", "hello")
      .map(fun.andThen(n -> n * 2));

A third way that may be more concise is with a utility method:

public static <T, X, U> Function<T, U> chain(Function<T, X> fun1, Function<X, U> fun2)
{
    return fun1.andThen(fun2);
}

Stream.of("ciao", "hola", "hello")
      .map(chain(String::length, n -> n * 2));

Please note that this is not tested, thus I don't know if type inference works correctly in this case.


You can just save it into a variable:

Function<String, Integer> toLength = String::length;
Stream.of("ciao", "hola", "hello")
      .map(toLength.andThen(n -> n * 2));

Or you can use a cast, but it's less readable, IMO:

Stream.of("ciao", "hola", "hello")
      .map(((Function<String, Integer>) String::length).andThen(n -> n * 2));

You can write a static method to do this:

import java.util.function.*;

class Test {
    public static void main(String[] args) {
        Function<String, Integer> function = combine(String::length, n -> n * 2);
        System.out.println(function.apply("foo"));
    }

    public static <T1, T2, T3> Function<T1, T3> combine(
        Function<T1, T2> first,
        Function<T2, T3> second) {
        return first.andThen(second);
    }
}

You could then put it in a utility class and import it statically.

Alternatively, create a simpler static method which just returns the function it's given, for the sake of the compiler knowing what you're doing:

import java.util.function.*;

class Test {
    public static void main(String[] args) {
        Function<String, Integer> function = asFunction(String::length).andThen(n -> n * 2);
        System.out.println(function.apply("foo"));
    }

    public static <T1, T2> Function<T1, T2> asFunction(Function<T1, T2> function) {
        return function;     
    }
}