I know of this one http://onjava.com/pub/a/onjava/2003/08/20/memoization.html but is there anything else?
Asked
Active
Viewed 2.1k times
24
-
1This example does memoization on all methods of an object via a proxy. But typical memoization is one function at the time. That proxy technique would be annoying when you dont want to memoize all the methods of an object. – lacroix1547 Sep 02 '10 at 05:45
3 Answers
23
To memoize functions without parameters, use Guava's Suppliers.memoize(Supplier)
. For functions with parameters, use CacheBuilder.build(CacheLoader)
with parameter value objects as keys.
-
-
Memoization example: https://stackoverflow.com/questions/3636244/thread-safe-cache-of-one-object-in-java/3636791#3636791 – Vadzim Jun 26 '17 at 10:38
17
Example:
import java.math.BigInteger;
import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
public class Fibonacci {
private static final LoadingCache<Integer, BigInteger> CACHE
= CacheBuilder.newBuilder().build(CacheLoader.from(Fibonacci::fib));
public static BigInteger fib(int n) {
Preconditions.checkArgument(n >= 0);
switch (n) {
case 0:
return BigInteger.ZERO;
case 1:
return BigInteger.ONE;
default:
return CACHE.getUnchecked(n - 1).add(CACHE.getUnchecked(n - 2));
}
}
}

C. K. Young
- 219,335
- 46
- 382
- 435
-
7MapMaker is now deprecated in favour of CacheBuilder: https://code.google.com/p/guava-libraries/wiki/MapMakerMigration – dzieciou Nov 08 '13 at 19:55
-
2@dzieciou I've finally updated the code to something that works with the latest Guava (18.0 at current time of writing). And this time, it's tested! – C. K. Young Mar 22 '15 at 05:35
15
Memoization is also easy with plain simple typesafe Java.
You can do it from scratch with the following reusable classes.
I use these as caches whose lifespan are the request on a webapp.
Of course use the Guava MapMaker
if you need an eviction strategy or more features like synchronization.
If you need to memoize a method with many parameters, just put the parameters in a list with both techniques, and pass that list as the single parameter.
abstract public class Memoize0<V> {
//the memory
private V value;
public V get() {
if (value == null) {
value = calc();
}
return value;
}
/**
* will implement the calculation that
* is to be remembered thanks to this class
*/
public abstract V calc();
}
abstract public class Memoize1<P, V> {
//The memory, it maps one calculation parameter to one calculation result
private Map<P, V> values = new HashMap<P, V>();
public V get(P p) {
if (!values.containsKey(p)) {
values.put(p, calc(p));
}
return values.get(p);
}
/**
* Will implement the calculations that are
* to be remembered thanks to this class
* (one calculation per distinct parameter)
*/
public abstract V calc(P p);
}
And this is used like this
Memoize0<String> configProvider = new Memoize0<String>() {
@Override
public String calc() {
return fetchConfigFromVerySlowDatabase();
}
};
final String config = configProvider.get();
Memoize1<Long, String> usernameProvider = new Memoize1<Long, String>() {
@Override
public String calc(Long id) {
return fetchUsernameFromVerySlowDatabase(id);
}
};
final String username = usernameProvider.get(123L);

NickAldwin
- 11,584
- 12
- 52
- 67

lacroix1547
- 1,060
- 1
- 8
- 16
-
-
Guava is not approved for our environment yet. Banking software... But this will do. I will limit the size of the map however to avoid memory leaks. I dont care about evictions since this will be conserved only during the invocation of one method. – ranv01 Sep 08 '10 at 02:31
-
45I like the way highly tested code is not approved, but something pasted on SO is :) – Rob Grant May 19 '14 at 06:39
-
1Be cautious using the Memoize0 example since it's not thread-safe. Multiples threads may call the calc() method numerous time in a race-condition. The Guava is implementation is thread-safe, lock-free on get() once initialized because it uses double-check locking : https://github.com/google/guava/blob/master/guava/src/com/google/common/base/Suppliers.java#L114 – Daniel Marcotte Aug 21 '15 at 15:22
-
It looks like `MapMaker` doesn't exist (anymore). Try [CacheBuilder](https://github.com/google/guava/wiki/CachesExplained) instead. – jpaugh Jul 25 '16 at 21:16
-
@RobertGrant Not surprising to me. Guava is big, while something tiny and purpose-built like this, using only stuff built in to Java, is easy to verify. – Izkata Aug 19 '18 at 06:19