Why can't we compose Function and Consumer just like we compose functions?
Function<Integer, String> a = Object::toString;
Consumer<String> b = x -> System.out.println(x);
Consumer<Integer> composed = a.andThen(b);
This seems like an obvious improvisation to the existing Function interface. Is there any reason why this capability was avoided in Java 8?
Also, is it a common practice to use an extended implementation of Function as follows?
interface FunctionImproved<T, R> extends Function<T, R> {
default Consumer<T> andThen(Consumer<R> consumer) {
return x -> consumer.accept(apply(x));
}
}
It's all about Java's type system. The
Function.andThen
method accepts an argument of typeFunction
(which is not of typeConsumer
). There's no relation between aConsumer
and aFunction
in Java, i.e. one doesn't extend the other one, so you can't pass aConsumer
toFunction
'sandThen
method.There are workarounds available, though. One is with a default method, as you showed, while another approach would be to use a static method, as shown in Andrew's answer.
Here's another way, using a higher-order function:
You can use it this way: