I am trying to create multiple CompletionStage of type List, eg. CompletionStage<List<Car>>
. And at the end I want to merge all the responses of type <List<Car>>
in to one List in one CompletionStage.
CompletionStage<List<Car>> completionStageOne= carClientOne.getCarList();
CompletionStage<List<Car>> completionStageTwo= carClientTwo.getCarList();
CompletionStage<List<Car>> completionStageThree= carClientThree.getCarList();
So Here, suppose I have 3 different services which will give me different list of car as in response form of CompletionStage<List<Car>>
Now I am trying to combine them and creating one common list of cars and here I am getting the problem. I am using the below code to combine the result
CompletionStage<List<Car>> completionStageOneTwo = completionStageOne
.thenCombine(completionStageTwo,(x, y) -> Stream.concat(x.stream(), y.stream()).collect(Collectors.toList()));
//above will work but if I add the third one then it will not.
CompletionStage<List<Car>> completionStageFinal = completionStageOneTwo
.thenCombine(completionStageThree,(x, y) -> Stream.concat(x.stream(), y.stream()).collect(Collectors.toList()));
and at the end I am doing
List<Car> finalList = completionStageFinal.toCompletableFuture().get();
So what I am doing wrong? How can I combine this three? Am I blocking something?
Note: I already checked this answer from Holger, but not able to figure out how to use concat there.
Let me show you an example. I will show how to use CompletableFuture.AllOf(...)
which allow waiting for all of the futures.
// create promises to get cars
CompletableFuture<List<String>> cars1 = CompletableFuture.completedFuture(Arrays.asList("BMW", "Alfa"));
CompletableFuture<List<String>> cars2 = CompletableFuture.completedFuture(Collections.singletonList("WV"));
CompletableFuture<List<String>> cars3 = CompletableFuture.completedFuture(Collections.singletonList("FIAT"));
// collect promises just for convenience
List<CompletableFuture<List<String>>> allFutures = Arrays.asList(cars1, cars2, cars3);
// wait until all cars will be obtained
CompletableFuture<List<String>> listCompletableFuture =
CompletableFuture.allOf(cars1, cars2, cars3)
.thenApply(avoid -> allFutures //start to collect them
.stream()
.flatMap(f -> f.join().stream()) //get List from feature. Here these cars has been obtained, therefore non blocking
.collect(Collectors.toList())
);
// there are here
listCompletableFuture.join().forEach(System.out::println);
Output:
BMW
Alfa
WV
FIAT