[英]Caching using Supplier Java 8
This method, as I know, memorizes (caches) the value of supplier that passed as the parameter. 据我所知,这种方法记忆(缓存)作为参数传递的供应商的价值。 As I understand It behaves like singleton pattern. 据我所知它表现得像单身模式。 Can anyone explain how it works? 谁能解释它是如何工作的?
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);
};
}
Usage like this: 用法如下:
Supplier<SomeClass> cachedValue = memoize(() -> someClassObject.getSomeValueToBeCached());
cachedValue.get().doMethod();
Ok, so let's rewrite the code in small steps towards more old-style, verbose Java. 好吧,让我们以较小的步骤重写代码,转向更老式,冗长的Java。 Maybe that makes it simpler to understand. 也许这使得理解起来更简单。
First step: get rid of the lambda: 第一步:摆脱lambda:
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);
}
};
}
Next step: extract the anonymous inner class into a standalone class. 下一步:将匿名内部类提取到独立类中。 While the anonymous class had access to the local variables of its containing method ( memoryList
), a "normal" class has not, so we're moving the list into the caching supplier. 虽然匿名类可以访问其包含方法( 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);
}
Finally, let's replace the ArrayList by a simple reference. 最后,让我们通过一个简单的引用替换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);
}
Maybe that's easier to understand. 也许这更容易理解。 If you are still unclear about something, just ask in a comment and I'll try to explain it. 如果您仍然不清楚某些事情,请在评论中提问,我会尝试解释它。
How about this? 这个怎么样?
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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.