The Function interface can encapsulate an operation, and allows chaining functions by using the compose and andThen methods.
Function<String,Integer>function;Integerresult;// Function initialization is skippedresult =function.apply("abc");
Chaining Functions
The interface contains default methods to chain operations through function composition:
Function<String,Integer>function1;Function<Integer,String>function2;Function<Integer,String>firstThenSecond;Function<Integer,String>secondThenFirst;// Function initialization is skipped// Apply function 1 then function 2firstThenSecond=function1.andThen(function2);// Apply function 2 then function 1secondThenFirst =function1.compose(function2);
Mapping Methods
Any method can be used as a function.
In this case an abstract method will be used as a strategy, to support the template method pattern. This method is as follows:
Then we have another method ready to make use of a function with the same erasure:
And now this can be used like this:
While at first this may be overly complex, take not that in a real application the second method would encapsulate complex operations, allowing the programmer to just change the particulars of the read operation:
Extensions
The JDK includes a BiFunction, which supports two arguments as input, and a few extensions for numeric primitives, and a binary operator which takes two instances of the same type.
protected abstract Iterable<T> onRead(final T sample);
private final <I, O> Iterable<O> read(final I sample, final Function<I, O> strategy)
{
// Additional operations goes here
return strategy.apply(sample);
}
public final read(final I sample) {
return read(input, this::onRead);
}
public final read1(final I sample) {
return read(input, this::onRead1);
}
public final read2(final I sample) {
return read(input, this::onRead2);
}
public final read3(final I sample) {
return read(input, this::onRead3);
}