Search code examples
javamemoization

What are the different techniques for memoization in Java?


I know of this one http://onjava.com/pub/a/onjava/2003/08/20/memoization.html but is there anything else?


Solution

  • 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);