How to convert List<Mono<T>> to Mono<List<T>>?

爷,独闯天下 提交于 2020-01-06 11:10:10

问题


I have a method that returns Mono<Output>:

interface Processor {
  Mono<Output> process(Input input);
}

And I want to execute this processor method for a collection:

List<Input> inputs = // get inputs
Processor processor = // get processor
List<Mono<Output>> outputs = inputs.stream().map(supplier::supply).collect(toList());

But instead of a List<Mono<Output>> I want to get Mono<List<Output>> that will contain aggregated results.

I tried reduce, but the final result looks very clumsy:

Mono<List<Output>> result = inputs.stream().map(processor::process)
    .reduce(Mono.just(new ArrayList<>()),
        (monoListOfOutput, monoOfOutput) ->
            monoListOfOutput.flatMap(list -> monoOfOutput.map(output -> {
              list.add(output);
              return list;
            })),
        (left, right) ->
            left.flatMap(leftList -> right.map(rightList -> {
              leftList.addAll(rightList);
              return leftList;
            })));

Can I achieve this with less code?


回答1:


If you don't have to create stream for any reason, you could create Flux from your inputs, map it and collect list

Flux.fromIterable(inputs).flatMap(processor::process).collectList();



回答2:


// first merge all the `Mono`s:
List<Mono<Output>> outputs = ...
Flux<Output> merged = Flux.empty();
for (Mono<Output> out : outputs) {
    merged = merged.mergeWith(out);
}

// then collect them
return merged.collectList();

or (inspired by Alexander's answer)

Flux.fromIterable(outputs).flatMap(x -> x).collectList();


来源:https://stackoverflow.com/questions/53231537/how-to-convert-listmonot-to-monolistt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!