据我所知,此方法存储(缓存)作为参数传递的供应商的值。据我所知,它的行为类似于单例模式。有人能解释一下它的工作原理吗?
public static <T> Supplier<T> memoize(final Supplier<? extends T> valueSupplier)
{
final List<T> memoryList= new ArrayList<>();
return () -> {
if (memoryList.isEmpty()) {
memoryList.add(valueSupplier.get());
}
return memoryList.get(0);
};
}这样的用法:
Supplier<SomeClass> cachedValue = memoize(() -> someClassObject.getSomeValueToBeCached());
cachedValue.get().doMethod();发布于 2017-05-25 09:41:24
好的,让我们用更老风格的、冗长的Java用小步骤重写代码。也许这会让我们更容易理解。
第一步:摆脱羔羊:
public static <T> Supplier<T> memoize(final Supplier<? extends T> valueSupplier)
{
final List<T> memoryList= new ArrayList<>();
return new Supplier<T>() {
@Override
public T get() {
if (memoryList.isEmpty()) {
memoryList.add(valueSupplier.get());
}
return memoryList.get(0);
}
};
}下一步:将匿名内部类提取为独立类。虽然匿名类可以访问其包含方法(memoryList)的局部变量,但是“普通”类没有访问,因此我们将列表移到缓存提供者中。
class CachingSupplier<T> implements Supplier<T> {
final List<T> memoryList= new ArrayList<>();
private Supplier<T> originalSupplier;
public CachingSupplier(Supplier<T> originalSupplier) {
this.originalSupplier = originalSupplier;
}
@Override
public T get() {
if (memoryList.isEmpty()) {
memoryList.add(originalSupplier.get());
}
return memoryList.get(0);
}
}
public static <T> Supplier<T> memoize(final Supplier<? extends T> valueSupplier) {
return new CachingSupplier<>(valueSupplier);
}最后,让我们用一个简单的引用来替换ArrayList。
class CachingSupplier<T> implements Supplier<T> {
private T cachedValue;
private Supplier<T> originalSupplier;
public CachingSupplier(Supplier<T> originalSupplier) {
this.originalSupplier = originalSupplier;
}
@Override
public T get() {
if (cachedValue == null) {
cachedValue = originalSupplier.get();
}
return cachedValue;
}
}
public static <T> Supplier<T> memoize(final Supplier<? extends T> valueSupplier) {
return new CachingSupplier<>(valueSupplier);
}也许这更容易理解。如果你对某些事情还不清楚,请发表评论,我会尽力解释的。
发布于 2017-05-25 09:36:46
这个怎么样?
public static <T> Supplier<T> memoize(final Supplier<? extends T> factory) {
final List<T> cache = new ArrayList<>();
return () -> {
// v--- check the value is cached?
if (cache.isEmpty()) {
// v--- return the value created by factory
cache.add(factory.get());
// ^--- adding the value into the cache
}
return cache.get(0);
// ^--- return the cached value
};
}用法
Supplier<String> factory = ()-> new String("foo");
assert factory.get() == factory.get(); // return false;
assert memoize(factory).get() == memoize(factory).get(); //return false;
// v--- storing the memoized factory for using as further
Supplier<String> memoized = memoize(original);
assert memoized.get() == memoized.get(); // return true.
// ^--- they are the same. https://stackoverflow.com/questions/44176953
复制相似问题