Java 中有哪些不同的记忆技术?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3623754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the different techniques for memoization in Java?
提问by ranv01
I know of this one http://onjava.com/pub/a/onjava/2003/08/20/memoization.htmlbut is there anything else?
我知道这个http://onjava.com/pub/a/onjava/2003/08/20/memoization.html但还有别的吗?
采纳答案by lacroix1547
Memoization is also easy with plain simple typesafe Java.
使用简单的类型安全 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.
我将它们用作缓存,其生命周期是 Web 应用程序上的请求。
Of course use the Guava MapMakerif you need an eviction strategy or more features like synchronization.
当然,MapMaker如果您需要驱逐策略或更多功能(如同步),请使用 Guava 。
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);
回答by thSoft
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.
要记住没有参数的函数,请使用 Guava 的Suppliers.memoize(Supplier). 对于带参数的函数,使用CacheBuilder.build(CacheLoader)参数值对象作为键。
回答by Chris Jester-Young
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));
}
}
}

