public static <T> CompletableFuture<T> combineFutures(
        List<CompletableFuture<T>> futures,
        Supplier<T> init,
        BiConsumer<T, T> add
    ) {
        final CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
        return allFutures.thenApply(v -> {
            final T res = init.get();
            futures.forEach(future -> add.accept(res, future.join()));
            return res;
        });
    }
Given a list of CompletableFutures returns a single CompletableFuture combining them.

@param futures       The list of futures.
@param init          The function to init the accumulator.
@param add           The function to accumulate the results. The function
                     takes the accumulator as a first argument and the new
                     results as a second argument.
@return A new CompletableFuture.
server-common/src/main/java/org/apache/kafka/server/util/FutureUtils.java