The issue is that your Factorial function does not call recursively into the memoized version of the function.
To fix this, there are a few options.
You could parameterize your Factorial function and give it reference to the
Function
it should call recursively. In the unmemoized case, this will be the function itself; in the memoized case, this will be the memoizing wrapper.You could implement memoization through extending the Factorial function class, overriding, rather than delegating to, the unmemoized
apply()
. This is difficult to do ad-hoc, but there are utilities out there to create subclasses dynamically (this is a common way of implementing AOP, for example).You could give the base function full knowledge of the memoization to start with.
Here's the gist of the first option:
interface MemoizableFunction<I, O> extends Function<I, O> {
//in apply, always recurse to the "recursive Function"
O apply(I input);
setRecursiveFunction(Function<? super I, ? extends O>);
}
final MemoizableFunction<Integer, Integer> fact = new MemoizableFunction<Integer, Integer>() {
private Function<Integer, Integer> recursiveFunction = this;
@Override
public Integer apply(final Integer input) {
System.out.println("Fact: " + input);
if(input == 1)
return 1;
else return input * recursiveFunction.apply(input -1);
}
//...
};