title: Convert from List<CompletableFuture> to CompletableFuture<List>
body: <p>I am trying to convert <code>List&lt;CompletableFuture&lt;X&gt;&gt;</code> to <code>CompletableFuture&lt;List&lt;T&gt;&gt;</code>. This is quite useful as when you have many asynchronous tasks and you need to get results of all of them.</p>
  <p>If any of them fails then the final future fails. This is how I have implemented:</p>
  <pre><code>public static &lt;T&gt; CompletableFuture&lt;List&lt;T&gt;&gt; sequence2(List&lt;CompletableFuture&lt;T&gt;&gt; com, ExecutorService exec) {
      if(com.isEmpty()){
          throw new IllegalArgumentException();
      }
      Stream&lt;? extends CompletableFuture&lt;T&gt;&gt; stream = com.stream();
      CompletableFuture&lt;List&lt;T&gt;&gt; init = CompletableFuture.completedFuture(new ArrayList&lt;T&gt;());
      return stream.reduce(init, (ls, fut) -&gt; ls.thenComposeAsync(x -&gt; fut.thenApplyAsync(y -&gt; {
          x.add(y);
          return x;
      },exec),exec), (a, b) -&gt; a.thenCombineAsync(b,(ls1,ls2)-&gt; {
          ls1.addAll(ls2);
          return ls1;
      },exec));
  }
  </code></pre>
  <p>To run it:</p>
  <pre><code>ExecutorService executorService = Executors.newCachedThreadPool();
  Stream&lt;CompletableFuture&lt;Integer&gt;&gt; que = IntStream.range(0,100000).boxed().map(x -&gt; CompletableFuture.supplyAsync(() -&gt; {
      try {
          Thread.sleep((long) (Math.random() * 10));
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      return x;
  }, executorService));
  CompletableFuture&lt;List&lt;Integer&gt;&gt; sequence = sequence2(que.collect(Collectors.toList()), executorService);
  </code></pre>
  <p>If any of them fails then it fails. It gives output as expected even if there are a million futures.  The problem I have is: Say if there are more than 5000 futures and if any of them fails, I get a <code>StackOverflowError</code>:</p>
  <blockquote>
  <p>Exception in thread &quot;pool-1-thread-2611&quot; java.lang.StackOverflowError
  at
  java.util.concurrent.CompletableFuture.internalComplete(CompletableFuture.java:210)
  at
  java.util.concurrent.CompletableFuture$ThenCompose.run(CompletableFuture.java:1487)
  at
  java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:193)
  at
  java.util.concurrent.CompletableFuture.internalComplete(CompletableFuture.java:210)
  at
  java.util.concurrent.CompletableFuture$ThenCompose.run(CompletableFuture.java:1487)</p>
  </blockquote>
  <p>What am I doing it wrong?</p>
  <p>Note: The above returned future fails right when any of the future fails. The accepted answer should also take this point.</p>