私はこれを知っています http://onjava.com/pub/a/onjava/2003/08/20/memoization.html しかし、他に何かありますか?
プレーンでシンプルなタイプセーフJavaを使用すると、メモ化も簡単です。
次の再利用可能なクラスを使用して、最初からそれを行うことができます。
私はこれらをキャッシュとして使用し、その存続期間はWebアプリでのリクエストです。
もちろん、エビクション戦略や同期などの機能が必要な場合は、Guava MapMaker
を使用してください。
多くのパラメーターを含むメソッドをメモ化する必要がある場合は、両方の手法を使用してパラメーターをリストに入れ、そのリストを単一のパラメーターとして渡します。
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);
パラメータなしで関数をメモ化するには、Guavaの Suppliers.memoize(Supplier)
を使用します。パラメータを持つ関数の場合、パラメータ値オブジェクトをキーとして CacheBuilder.build(CacheLoader)
を使用します。
例:
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));
}
}
}