A Small Exercise with Java's CompletableFuture
One of the cool features about Reactive Java is the Mono::zip or Flux::zip which allows you to combine unrelated Mono/Flux results:
I was doing some Java optimization the other day and was forced into using CompletableFuture constructs (it was using Java 8), it was the one thing that I needed.
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 1);
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<Double> future3 = CompletableFuture.supplyAsync(() -> 3.14);
Every solution i found out there (which includes ChatGPT) is recommending CompletableFuture::allOf which IMO is not very clean/elegant (less idiomatic)
var combinedFuture = CompletableFuture.allOf(future1, future2, future3)
.thenApply(v -> {
try {
Integer result1 = future1.get();
String result2 = future2.get();
Double result3 = future3.get();
return new Tuple.of(result1, result2, result3);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
(Note that I’m using vavr’s Tuple type since Java 8 doesn’t have it)
After much thinking I came up with this solution:
var combinedResults = future1
.thenCombine(future2, Tuple::of)
.thenApply(future3, (t, e) -> t.concat(Tuple.of(e)));
The clear take-away here is nobody should be thinking about these things on a Thanksgiving long weekend. ??
Principal Member @ Oracle | Ex-Vmware
3 个月For some reason i find the first option more readable, where in the second option its like if you dont understand this dont join my team ?? Maybe i would write a small comment on top of the code, for new folks to not beat their head understanding the code ?