---
title: Concatenate list of CompletableFuture<T>
tags: ["CompletableFuture", "Java SE 8"]
categories: ["Programming", "Java", "java", "util", "concurrent", "CompletableFuture"]
date: 2015-10-10T08:50:14Z
updated: 2015-10-10T08:50:14Z
---

When you want to Concatenate the list of `CompletableFuture<T>`, `CompletableFuture#allOf` is really inconvenient because the result type of the method is unfortunately `CompletableFuture<Void>`.

``` java
CompletableFuture<List<GitHubStar>> f1 = findStars("aaa");
CompletableFuture<List<GitHubStar>> f2 = findStars("bbb");
CompletableFuture<List<GitHubStar>> f3 = findStars("ccc");

CompletableFuture<Void> result = CompletableFuture.allOf(f1, f2, f3); // Void...! I want to merge the results :S
```

Instead of `allOf`, `thenCombine` is useful.

``` java
CompletableFuture<List<GitHubStar>> f1 = findStars("aaa");
CompletableFuture<List<GitHubStar>> f2 = findStars("bbb");

CompletableFuture<List<GitHubStar>> result = f1.thenCombine(f2, (l1, l2) -> {
    l1.addAll(l2);
    return l1;
});
```

But how about combining `List<CompletableFuture<List<GitHubStar>>>`?
You can use `Stream#reduce`.

``` java
Optional<CompletableFuture<List<GitHubStar>>> ret = usernames.stream()
        .map(main::findStars)
        .reduce((f1, f2) -> f1.thenCombine(f2, (l1, l2) -> {
            l1.addAll(l2);
            return l1;
        }));
ret.get().thenAccept(stars -> stars.stream()
                .distinct()
                .sorted(Comparator.comparing(GitHubStar::getUpdatedAt).reversed())
                .forEach(System.out::println)
).get();
```

Sample code is [here](https://gist.github.com/making/0fabbaa4f7bc4e7dcfba).
