Java – CompletableFuture | thenApply vs thenCompose

completable-futurejavajava-8

I can't get my head around the difference between thenApply() and thenCompose().

So, could someone provide a valid use case?

From the Java docs:

thenApply(Function<? super T,? extends U> fn)

Returns a new CompletionStage that, when this stage completes
normally, is executed with this stage's result as the argument to the
supplied function.

thenCompose(Function<? super T,? extends CompletionStage<U>> fn)

Returns a new CompletionStage that, when this stage completes
normally, is executed with this stage as the argument to the supplied
function.

I get that the 2nd argument of thenCompose extends the CompletionStage where thenApply does not.

Could someone provide an example in which case I have to use thenApply and when thenCompose?

Best Answer

thenApply is used if you have a synchronous mapping function.

CompletableFuture<Integer> future = 
    CompletableFuture.supplyAsync(() -> 1)
                     .thenApply(x -> x+1);

thenCompose is used if you have an asynchronous mapping function (i.e. one that returns a CompletableFuture). It will then return a future with the result directly, rather than a nested future.

CompletableFuture<Integer> future = 
    CompletableFuture.supplyAsync(() -> 1)
                     .thenCompose(x -> CompletableFuture.supplyAsync(() -> x+1));