开发者

What are the different techniques for memoization in Java? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
开发者_StackOverflow

Want to improve this question? Update the question so it focuses on one problem only by editing this post.

Closed 5 years ago.

Improve this question

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


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.


Yes. Use caches from Guava.

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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜