code: public static <T> CompletableFuture<T> allOf(
        List<CompletableFuture<T>> futures, BinaryOperator<T> reducer, T emptyValue) {
      return allOf(futures).thenApply(resultList -> resultList.stream().reduce(reducer).orElse(emptyValue));
    }
docs: Returns a new CompletableFuture completed by reducing a list of computed values
  when all of the given CompletableFuture complete.
  
  @param futures    the CompletableFutures
  @param reducer    reducer for computing the result
  @param emptyValue zero value to be returned if the input future list is empty
  @param <T>        value type of CompletableFuture
  @return a new CompletableFuture that is completed when all of the given CompletableFutures complete