Skip to content

Instantly share code, notes, and snippets.

@Quackster
Created October 28, 2025 03:37
Show Gist options
  • Select an option

  • Save Quackster/32fd7487843f77ee63357446e1420d08 to your computer and use it in GitHub Desktop.

Select an option

Save Quackster/32fd7487843f77ee63357446e1420d08 to your computer and use it in GitHub Desktop.
Java Lazily Load Library
// Value.java
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* A container that holds a value and supports both eager and lazy transformations.
* Provides synchronous and asynchronous computation capabilities.
*
* @param <T> the type of the contained value
*/
public class Value<T> {
private final T value;
/**
* Creates a new Value with the given value.
*
* @param value the value to wrap
*/
public Value(T value) {
this.value = value;
}
/**
* Returns the contained value.
*
* @return the value
*/
public T value() {
return value;
}
/**
* Applies a transformation function eagerly and returns a new Value.
*
* @param <R> the result type
* @param mapper the transformation function
* @return a new Value containing the transformed value
*/
public <R> Value<R> apply(Function<T, R> mapper) {
return new Value<>(mapper.apply(value));
}
/**
* Applies a transformation function lazily and returns a LazyValue.
* The computation is deferred until value() is called on the LazyValue.
*
* @param <R> the result type
* @param mapper the transformation function
* @return a LazyValue that will compute the result when accessed
*/
public <R> LazyValue<R> applyLazy(Function<T, R> mapper) {
return new LazyValue<>(() -> mapper.apply(value));
}
/**
* Applies a transformation function asynchronously using CompletableFuture.
*
* @param <R> the result type
* @param mapper the transformation function
* @return an AsyncValue wrapping a CompletableFuture
*/
public <R> AsyncValue<R> applyAsync(Function<T, R> mapper) {
CompletableFuture<R> future = CompletableFuture.supplyAsync(() -> mapper.apply(value));
return new AsyncValue<>(future);
}
@Override
public String toString() {
return "Value{" + value + "}";
}
}
// LazyValue.java
/**
* A lazily-evaluated value that computes its result only when accessed.
* Once computed, the result is cached for subsequent accesses.
*
* @param <T> the type of the contained value
*/
class LazyValue<T> {
private final Supplier<T> supplier;
private volatile T cachedValue;
private volatile boolean computed = false;
/**
* Creates a new LazyValue with the given supplier.
*
* @param supplier the supplier that computes the value
*/
public LazyValue(Supplier<T> supplier) {
this.supplier = supplier;
}
/**
* Gets the value, computing it if necessary.
* The result is cached after the first computation.
*
* @return a Lazy wrapper containing the computed value
*/
public Lazy<T> value() {
return new Lazy<>(this::get);
}
/**
* Computes and returns the value, using cached result if available.
*
* @return the computed value
*/
private T get() {
if (!computed) {
synchronized (this) {
if (!computed) {
cachedValue = supplier.get();
computed = true;
}
}
}
return cachedValue;
}
/**
* Applies a transformation function eagerly to the lazy value.
*
* @param <R> the result type
* @param mapper the transformation function
* @return a new Value containing the transformed result
*/
public <R> Value<R> apply(Function<T, R> mapper) {
return new Value<>(mapper.apply(get()));
}
/**
* Applies a transformation function lazily.
*
* @param <R> the result type
* @param mapper the transformation function
* @return a new LazyValue that chains the transformations
*/
public <R> LazyValue<R> applyLazy(Function<T, R> mapper) {
return new LazyValue<>(() -> mapper.apply(get()));
}
/**
* Applies a transformation function asynchronously.
*
* @param <R> the result type
* @param mapper the transformation function
* @return an AsyncValue wrapping a CompletableFuture
*/
public <R> AsyncValue<R> applyAsync(Function<T, R> mapper) {
CompletableFuture<R> future = CompletableFuture.supplyAsync(() -> mapper.apply(get()));
return new AsyncValue<>(future);
}
@Override
public String toString() {
return computed ? "LazyValue{computed=" + cachedValue + "}" : "LazyValue{not computed}";
}
}
// Lazy.java
/**
* A simple wrapper that provides lazy access to a value.
*
* @param <T> the type of the contained value
*/
class Lazy<T> {
private final Supplier<T> supplier;
public Lazy(Supplier<T> supplier) {
this.supplier = supplier;
}
/**
* Gets the value from the supplier.
*
* @return the value
*/
public T get() {
return supplier.get();
}
@Override
public String toString() {
return "Lazy{...}";
}
}
// AsyncValue.java
/**
* A value that is computed asynchronously using CompletableFuture.
*
* @param <T> the type of the contained value
*/
class AsyncValue<T> {
private final CompletableFuture<T> future;
/**
* Creates a new AsyncValue wrapping a CompletableFuture.
*
* @param future the CompletableFuture to wrap
*/
public AsyncValue(CompletableFuture<T> future) {
this.future = future;
}
/**
* Returns the underlying CompletableFuture.
*
* @return the CompletableFuture
*/
public CompletableFuture<T> value() {
return future;
}
/**
* Applies a transformation function to the future result.
*
* @param <R> the result type
* @param mapper the transformation function
* @return a new AsyncValue with the transformed result
*/
public <R> AsyncValue<R> apply(Function<T, R> mapper) {
return new AsyncValue<>(future.thenApply(mapper));
}
/**
* Applies a transformation function asynchronously to the future result.
*
* @param <R> the result type
* @param mapper the transformation function
* @return a new AsyncValue with the transformed result
*/
public <R> AsyncValue<R> applyAsync(Function<T, R> mapper) {
return new AsyncValue<>(future.thenApplyAsync(mapper));
}
/**
* Blocks and gets the result from the CompletableFuture.
*
* @return the computed value
*/
public T get() {
try {
return future.get();
} catch (Exception e) {
throw new RuntimeException("Failed to get async value", e);
}
}
@Override
public String toString() {
return "AsyncValue{future=" + (future.isDone() ? "completed" : "pending") + "}";
}
}
// BoxExamples.java
/**
* Example usage of the lazy load library.
*/
public class BoxExamples {
public static void main(String[] args) throws Exception {
// Example 1: Eager evaluation
Value<Integer> num = new Value<>(5);
Value<Integer> doubled = num.apply(n -> n * 2);
System.out.println("Doubled: " + doubled.value());
// Example 2: Lazy evaluation
var doubled2 = num.applyLazy(n -> n * 2);
System.out.println("Doubled2: " + doubled2.value().get());
// Example 3: Chaining on lazy value
Value<Integer> doubled3 = doubled.apply(n -> n);
System.out.println("Doubled3: " + doubled3.value());
// Example 4: Async evaluation
System.out.println("\n--- Async Examples ---");
AsyncValue<Integer> asyncDoubled = num.applyAsync(n -> {
System.out.println("Computing async...");
return n * 2;
});
System.out.println("Result: " + asyncDoubled.value().get());
// Example 5: Chaining async operations
AsyncValue<Integer> asyncChained = asyncDoubled
.apply(n -> n + 10)
.applyAsync(n -> n * 3);
System.out.println("Chained async result: " + asyncChained.get());
// Example 6: Lazy chain
System.out.println("\n--- Lazy Chain ---");
LazyValue<Integer> lazyChain = num.applyLazy(n -> {
System.out.println("Step 1: " + n);
return n * 2;
}).applyLazy(n -> {
System.out.println("Step 2: " + n);
return n + 5;
});
System.out.println("Before evaluation: " + lazyChain);
System.out.println("Evaluated result: " + lazyChain.value().get());
System.out.println("After evaluation: " + lazyChain);
// Example 7: Async with delay and callbacks
System.out.println("\n--- Async with Delay and Callbacks ---");
System.out.println("Starting async operation at: " + System.currentTimeMillis());
Value<String> message = new Value<>("Hello");
AsyncValue<String> delayedAsync = message.applyAsync(msg -> {
try {
System.out.println("Processing started... (will take 2 seconds)");
Thread.sleep(2000); // 2 second delay
return msg + " World!";
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
// Attach callbacks using CompletableFuture's thenAccept
delayedAsync.value()
.thenAccept(result -> {
System.out.println("Callback 1 - Result received: " + result);
System.out.println("Completed at: " + System.currentTimeMillis());
})
.thenRun(() -> System.out.println("Callback 2 - All done!"));
System.out.println("Main thread continues immediately...");
// Chain more operations with delays
AsyncValue<Integer> multiStep = new Value<>(1)
.applyAsync(n -> {
sleep(500);
System.out.println("Step 1 complete: " + n);
return n * 2;
})
.applyAsync(n -> {
sleep(500);
System.out.println("Step 2 complete: " + n);
return n + 10;
})
.applyAsync(n -> {
sleep(500);
System.out.println("Step 3 complete: " + n);
return n * 3;
});
// Handle completion and errors
multiStep.value()
.whenComplete((result, error) -> {
if (error != null) {
System.out.println("Error occurred: " + error.getMessage());
} else {
System.out.println("Final result: " + result);
}
});
// Wait for all async operations to complete
Thread.sleep(3000);
System.out.println("\n--- All operations completed ---");
}
private static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment