Wrapper for lazy loaded values

This commit is contained in:
Marc Baloup 2021-08-08 12:56:36 +02:00
parent 7a19f543cc
commit 425527ddb2
Signed by: marcbal
GPG Key ID: BBC0FE3ABC30B893
2 changed files with 100 additions and 0 deletions

View File

@ -0,0 +1,48 @@
package fr.pandacube.lib.core.util;
import java.util.Objects;
import java.util.function.Supplier;
/**
* Represents a lazy loaded value.
*
* The value will be computed using the Supplier provided in the
* constructor, only the first time the {@link #get()} method is
* called.
*
* @param <T> the type of the enclosed value.
*/
public class Lazy<T> implements Supplier<T> {
private T cachedValue;
private final Supplier<T> supplier;
private boolean cached = false;
public Lazy(Supplier<T> s) {
supplier = Objects.requireNonNull(s);
}
/**
* Get the wrapped value, from cache or from the provider if it is not yet cached.
*
* If the provider throws an exception, it will be redirected to the caller as is, and no value will be cached (the next call to this method will
* execute the supplier again).
*/
@Override
public synchronized T get() {
if (!cached) // check outside synchronized method to reduce useless synchronization if value is already cached
set(supplier.get());
return cachedValue;
}
public synchronized void reset() {
cached = false;
cachedValue = null;
}
public synchronized void set(T value) {
cachedValue = value;
cached = true;
}
}

View File

@ -0,0 +1,52 @@
package fr.pandacube.lib.core.util;
import java.util.Objects;
/**
* Represents a lazy loaded value.
*
* The value will be computed using the Supplier provided in the
* constructor, only the first time the {@link #get()} method is
* called.
*
* @param <T> the type of the enclosed value.
*/
public class LazyOrException<T> {
private T cachedValue;
private final SupplierException<T> supplier;
private boolean cached = false;
public LazyOrException(SupplierException<T> s) {
supplier = Objects.requireNonNull(s);
}
/**
* Get the wrapped value, from cache or from the provider if it is not yet cached.
*
* If the provider throws an exception, it will be redirected to the caller as is, and no value will be cached (the next call to this method will
* execute the supplier again).
*/
public synchronized T get() throws Exception {
if (!cached) // check outside synchronized method to reduce useless synchronization if value is already cached
set(supplier.get());
return cachedValue;
}
public synchronized void reset() {
cached = false;
cachedValue = null;
}
public synchronized void set(T value) {
cachedValue = value;
cached = true;
}
@FunctionalInterface
public interface SupplierException<T> {
public T get() throws Exception;
}
}