java-commons/src/main/java/io/gitlab/jfronny/commons/LazySupplier.java

54 lines
1.8 KiB
Java

package io.gitlab.jfronny.commons;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* A supplier that proxies to a separate supplier and caches its result
*/
public class LazySupplier<T> implements Supplier<T> {
private final Supplier<T> supplier;
private T cache = null;
/**
* Create a lazy supplier from a pre-initialized value.
* The backing supplier will be empty and never called.
* @param value The value to initialize the cache with
*/
public LazySupplier(@NotNull T value) {
this.supplier = () -> {
throw new RuntimeException("Supplier should have never been called");
};
cache = value;
}
/**
* Create a lazy supplier backed with the specified supplier.
* It will at most be called once when this supplier is first used.
* @param supplier The backing supplier
*/
public LazySupplier(@NotNull Supplier<T> supplier) {
this.supplier = Objects.requireNonNull(supplier);
}
@Override @Contract(pure = true) @NotNull public T get() {
if (cache == null) cache = supplier.get();
return cache;
}
/**
* Generates a new lazy supplier from a function.
* This function is provided with this lazy supplier as a data source for transformation.
* Allows complex transformations to not be run if a later supplier has a shortcut
* @param after A backing function for the new lazy supplier
* @return A new lazy supplier
*/
@Contract(pure = true) @NotNull public LazySupplier<T> andThen(@NotNull Function<LazySupplier<T>, T> after) {
return new LazySupplier<>(() -> after.apply(this));
}
}