Memoizer
Cache the result of any pure function.
Memoizer wraps a pure Function, BiFunction or TriFunction so subsequent calls with the same arguments are served from cache.
Function<Integer, Long> slowFib = Memoizer.memoize(n ->
n < 2 ? n : slowFib.apply(n-1) + slowFib.apply(n-2));
slowFib.apply(40); // fast — even though the body is naïve
Memoization only makes sense for pure functions. Caching the result of a function with side-effects (logging, DB writes) will silently change behaviour.