fego
fego

Reputation: 311

Chaining stream of CompletableFuture or chaining CompletableFuture?

I don't see a major difference between this:

List<CompletableFuture<Integer>> intFutures = Stream.of(1, 2, 3, 4)
    .map(input -> CompletableFuture.supplyAsync(() -> computeSomethingLong(input)))
    .map(future -> future.thenApply(input -> input * 2))
    .map(future -> future.thenCompose(computed -> CompletableFuture.supplyAsync(() -> computeSomethingLong(computed))))
    .collect(toList());

And this:

List<CompletableFuture<Integer>> intFutures = Stream.of(1, 2, 3, 4)
    .map(input -> CompletableFuture.supplyAsync(() -> computeSomethingLong(input))
            .thenApply(computed -> computed * 2)
            .thenCompose(computed -> CompletableFuture.supplyAsync(() -> computeSomethingLong(computed))))
    .collect(toList());

I have made a test and the result and the execution time is the same. The only difference I can see is that the second proposal allows the access to the input variable along the chain. So if I need it later in another task I can using it.

Am I wrong? Are there other differences?

Upvotes: 1

Views: 413

Answers (1)

knittl
knittl

Reputation: 265271

Your conclusion is correct. There is (almost) no difference – calling map multiple times might allocate a bit more memory, because a new stream instance needs to be created and returned. Semantically, both forms are equivalent and produce the same result.

If you need access to the initial value of your input, then you need to combine the operations into a single operation; otherwise the variable is not available in the operation's (i.e. lambda) scope.

More generally:

stream
    .map(x -> operation1(x))
    .map(x -> operation2(x))
    .map(x -> operation3(x))
    .toList();
// is equivalent to:
stream
   .map(x -> operation3(operation2(operation1(x))))
   .toList();

Or with method calls:

stream
    .map(x -> x.method1())
    .map(x -> x.method2())
    .map(x -> x.method3())
    .toList();
// equivalent to:
stream
    .map(x -> x.method1().method2().method3())
    .toList();

Upvotes: 1

Related Questions