IK.AM

@making's tech note


Concatenate list of CompletableFuture<T>

🗃 {Programming/Java/java/util/concurrent/CompletableFuture}
🏷 CompletableFuture 🏷 Java SE 8 
🗓 Updated at 2015-10-10T08:50:14Z  🗓 Created at 2015-10-10T08:50:14Z   🌎 English Page

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>.

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.

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.

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.


✒️️ Edit  ⏰ History  🗑 Delete