import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
static CompletableFuture<List<?>> allOf(CompletableFuture<?>... cfs) {
return CompletableFuture.allOf(cfs)
.thenApply(ignore -> Stream.of(cfs)
.map(cf -> cf.join())
.collect(Collectors.toList()));
}
public static void main(String[] args) {
// we have 3 (or any number) of CompletableFutures
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {sleep(1); return "HELLO";});
CompletableFuture<Integer> cf2 = CompletableFuture.supplyAsync(() -> {sleep(1); return 10;});
CompletableFuture<Double> cf3 = CompletableFuture.supplyAsync(() -> {sleep(1); return 20d;});
CompletableFuture<List<?>> allOf = allOf(cf1, cf2, cf3); //we call the method we just created above
// we can get the -already there - result either using then
// Get result using:
allOf.thenAccept(l -> l.forEach(System.out::println));
// or using CompletableFuture.join() (or CompletableFuture.get())
// OR (non-typesafe)
String s = (String) allOf.join().get(0);
Integer i = (Integer) allOf.join().get(1);
Double d = (Double) allOf.join().get(2);
System.out.println(s + ", " + i + ", "+ d);
sleep(2); // because default CompletableFuture Executor is a daemon-thread based executor
}
private static void sleep(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}