import java.util.concurrent.*;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.List;
public class AsyncUtils {
// Simple async execution
public static <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier) {
return CompletableFuture.supplyAsync(supplier);
}
// Async execution with custom executor
public static <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier, ExecutorService executor) {
return CompletableFuture.supplyAsync(supplier, executor);
}
// Transform result
public static <T, R> CompletableFuture<R> thenApply(CompletableFuture<T> future, Function<T, R> mapper) {
return future.thenApply(mapper);
}
// Chain futures
public static <T, R> CompletableFuture<R> thenCompose(CompletableFuture<T> future, Function<T, CompletableFuture<R>> mapper) {
return future.thenCompose(mapper);
}
// Combine two futures
public static <T, U, R> CompletableFuture<R> thenCombine(CompletableFuture<T> future1, CompletableFuture<U> future2, BiFunction<T, U, R> combiner) {
return future1.thenCombine(future2, combiner);
}
// Wait for all futures
public static CompletableFuture<Void> allOf(List<CompletableFuture<?>> futures) {
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
}
// Wait for any future
public static <T> CompletableFuture<Object> anyOf(List<CompletableFuture<T>> futures) {
return CompletableFuture.anyOf(futures.toArray(new CompletableFuture[0]));
}
// Handle exceptions
public static <T> CompletableFuture<T> handle(CompletableFuture<T> future, BiFunction<T, Throwable, T> handler) {
return future.handle(handler);
}
}