Last active
October 11, 2021 14:44
-
-
Save sujeet100/6647e90f916fd42bfccc898b92e877f7 to your computer and use it in GitHub Desktop.
Completable Futures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sujit; | |
import java.util.List; | |
import java.util.concurrent.CompletableFuture; | |
import java.util.concurrent.ExecutionException; | |
record Person(int id, String name, List<Score> scores, Address address, Account account) { | |
} | |
record Score(String subject, int marks) { | |
} | |
record Address(String city, String pin) { | |
} | |
record Account(String accountNumber, int balance) { | |
} | |
public class MyFutures { | |
public static void main(String[] args) throws ExecutionException, InterruptedException { | |
final List<String> subjects = List.of("Maths", "Physics"); | |
List<Integer> ids = List.of(1, 2, 3); | |
List<CompletableFuture<Person>> personsFuture = ids.stream().map(id -> getPerson(subjects, id)).toList(); | |
CompletableFuture<List<Person>> persons = sequence(personsFuture); | |
System.out.println(persons.get()); | |
} | |
private static CompletableFuture<Person> getPerson(List<String> subjects, Integer id) { | |
println("Get Person: " + id); | |
CompletableFuture<List<Score>> scores = getScores(id, subjects); | |
CompletableFuture<Address> address = CompletableFuture.supplyAsync(() -> getAddress(id)); | |
CompletableFuture<Account> account = CompletableFuture.supplyAsync(() -> getAccount(id)); | |
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(scores, address, account); | |
scores.whenComplete((x, e) -> println("Got scores: " + id)); | |
address.whenComplete((x, e) -> println("Got address: " + id)); | |
account.whenComplete((x, e) -> println("Got account: " + id)); | |
return combinedFuture.thenApply(v -> { | |
println("Got scores, address, account: " + id); | |
return new Person(id, | |
"name" + id, | |
scores.join(), | |
address.join(), | |
account.join()); | |
}); | |
} | |
private static CompletableFuture<List<Score>> getScores(int id, List<String> subjects) { | |
println("Get Scores: " + id); | |
List<CompletableFuture<Score>> scoresFuture = subjects.stream().map(subject -> { | |
CompletableFuture<Score> scoreFuture = CompletableFuture.supplyAsync(() -> getScore(id, subject)); | |
scoreFuture.whenComplete((x, e) -> println("Got score: " + id)); | |
return scoreFuture; | |
}).toList(); | |
return sequence(scoresFuture); | |
} | |
private static Score getScore(int id, String subject) { | |
println("Get Score: " + id + ", sub: " + subject); | |
try { | |
Thread.sleep(300); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return new Score(subject, id * 10); | |
} | |
static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> com) { | |
return CompletableFuture.allOf(com.toArray(new CompletableFuture[0])) | |
.thenApply(v -> com.stream() | |
.map(CompletableFuture::join) | |
.toList() | |
); | |
} | |
private static Address getAddress(int id) { | |
println("Get Address: " + id); | |
try { | |
Thread.sleep(200); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return new Address(id + "City", id + "101"); | |
} | |
private static Account getAccount(int id) { | |
println("Get Account: " + id); | |
try { | |
Thread.sleep(400); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return new Account(id + "9090", id * 1000); | |
} | |
private static void println(String message) { | |
System.out.println(Thread.currentThread().getName() + ": " + message); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment