Подтвердить что ты не робот

Каковы различные методы для memoization в Java?

Я знаю об этом http://onjava.com/pub/a/onjava/2003/08/20/memoization.html, но есть ли что-нибудь еще?

4b9b3361

Ответ 1

Запоминание также легко с простой простой Java-формой.

Вы можете сделать это с нуля со следующими классами повторного использования.

Я использую их как кеши, чей срок службы является запросом на webapp.

Конечно, используйте Guava MapMaker, если вам нужна стратегия выселения или другие функции, такие как синхронизация.

Если вам нужно memoize метод со многими параметрами, просто поместите параметры в список с помощью обоих методов и передайте этот список как единственный параметр.

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

И это используется как

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

Ответ 2

Для memoize функций без параметров используйте Guava Suppliers.memoize(Supplier). Для функций с параметрами используйте CacheBuilder.build(CacheLoader) с объектами значения параметра в качестве ключей.

Ответ 3

Да. Используйте caches из Guava.

Пример:

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