Как объединить несколько ответов CompletionStage типа List (для меня) или некоторые другие в Java - PullRequest
0 голосов
/ 28 августа 2018

Я пытаюсь создать несколько CompletionStage типа List, например. CompletionStage<List<Car>>. И в конце я хочу объединить все ответы типа <List<Car>> в один список в один CompletionStage .

CompletionStage<List<Car>> completionStageOne= carClientOne.getCarList();
CompletionStage<List<Car>> completionStageTwo= carClientTwo.getCarList();
CompletionStage<List<Car>> completionStageThree= carClientThree.getCarList();

Итак, предположим, у меня есть 3 разных сервиса, которые предоставят мне другой список автомобилей, как в форме ответа CompletionStage<List<Car>>

Теперь я пытаюсь объединить их и создать один общий список автомобилей, и здесь у меня возникает проблема. Я использую код ниже, чтобы объединить результат

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())); 

и в конце я делаю

List<Car> finalList = completionStageFinal.toCompletableFuture().get();

Так что я делаю не так? Как я могу объединить эти три? Я что-то блокирую?

Примечание: я уже проверил этот ответ от Хольгера , но не смог понять, как использовать concat там.

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Я действительно столкнулся с той же проблемой, и у меня есть пример того, как я использовал несколько завершаемых вариантов будущего для создания объекта.

https://github.com/te21wals/CompletableFuturesDemo

Это немного более "предприимчиво", чем нужно, но вы должны быть в состоянии понять идею.

public static void main (String[] args){
    CompletableFuture<ClassA> classAfuture = futureProvider.retrieveClassA();
    CompletableFuture<ClassB> classBfuture = futureProvider.retrieveClassB();
    CompletableFuture<ClassC> classCfuture = futureProvider.retrieveClassC();

    System.out.println("starting completable futures ...");
    long startTime = System.nanoTime();

    ABCData ABCData = CompletableFuture.allOf(classAfuture, classBfuture, classCfuture)
            .thenApply(ignored ->
                    combineFunction.combind(
                            classAfuture.join(),
                            classBfuture.join(),
                            classCfuture.join())
            ).join();

    long endTime = System.nanoTime();
    long duration = (endTime - startTime);
    System.out.println("completable futures are complete...");
    System.out.println("duration:\t" + Duration.ofNanos(duration).toString());
    System.out.println("result:\t" + ABCData);
} 

Приятным дополнительным преимуществом, которое вы получаете, является то, что общий запрос занимает время только самого длинного индивидуального запроса.

0 голосов
/ 29 августа 2018

Позвольте мне показать вам пример. Я покажу, как использовать CompletableFuture.AllOf(...), который позволяет ожидать все фьючерсы.

    // 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);

Выход:

BMW
Alfa
WV
FIAT
...