Search code examples
javajava-8completable-future

CompletableFuture | thenApply vs thenCompose


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?


Solution

  • 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));