8

Why is CompletableFuture.allOf declared as CompletableFuture<Void> and not returning collection of results or something else? I think that was good idea to make CompletableFuture.anyOf return CompletableFuture<Object>, but I see these two methods connected and so I'm confused about what they return.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Everv0id
  • 1,862
  • 3
  • 25
  • 47

2 Answers2

9

anyOf has to somehow tell you what was the result of the specific CompletableFuture whose completion triggered anyOf. That's not necessary in case of allOf because you know which futures completed -- all of them.

allOf (just as anyOf) doesn't require that all futures bear the same type. So if it were to return a future of collection, it would have to be a collection of Object which is probably not what you want anyway.

If you really want to have allOf return a future of collection, it's fairly straightforward to write your own:

public static CompletableFuture<List<Object>> myAllOf(CompletableFuture<?>... futures) {
     return CompletableFuture.allOf(futures)
            .thenApply(x -> Arrays.stream(futures)
                    .map(f -> (Object) f.join())
                    .collect(toList())
            );
}

If you have a type-safe version of this problem and need to convert a collection of futures of a certain type to a future of collection of that same type, see this question for several examples: List<Future> to Future<List> sequence

Community
  • 1
  • 1
Misha
  • 27,433
  • 6
  • 62
  • 78
  • Thanks for your explanation, but anyway I cant understand why `allOf` cant return stream of CompletableFuture or results or smth else... – Everv0id Dec 04 '15 at 12:36
1

This is similar to Misha's answer, but with a generic type:

public class Futures {
    public static <T> CompletableFuture<List<T>> all(List<CompletableFuture<T>> futures) {
        CompletableFuture<Void> cfv = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
        return cfv.thenApply(future -> {
            return futures.stream()
                    .map(completableFuture -> completableFuture.join())
                    .collect(Collectors.toList());
        });
    }
}

That's the method the Java API should provide.

Jose Solorzano
  • 393
  • 4
  • 6