#spring-boot #spring-webflux
#Ява #проект-реактор #реактор
Вопрос:
У меня есть метод, который возвращает Monolt;Outputgt;
:
interface Processor { Monolt;Outputgt; process(Input input); }
И я хочу выполнить этот processor
метод для коллекции:
Listlt;Inputgt; inputs = // get inputs Processor processor = // get processor Listlt;Monolt;Outputgt;gt; outputs = inputs.stream().map(supplier::supply).collect(toList());
Но вместо a Listlt;Monolt;Outputgt;gt;
я хочу получить Monolt;Listlt;Outputgt;gt;
то, что будет содержать агрегированные результаты.
Я пытался reduce
, но конечный результат выглядит очень неуклюжим:
Monolt;Listlt;Outputgt;gt; result = inputs.stream().map(processor::process) .reduce(Mono.just(new ArrayListlt;gt;()), (monoListOfOutput, monoOfOutput) -gt; monoListOfOutput.flatMap(list -gt; monoOfOutput.map(output -gt; { list.add(output); return list; })), (left, right) -gt; left.flatMap(leftList -gt; right.map(rightList -gt; { leftList.addAll(rightList); return leftList; })));
Могу ли я добиться этого с меньшим количеством кода?
Комментарии:
1. Вы могли бы просто обернуть свой вызов «собрать(список)» с помощью Mono.just и использовать карту(Mono::block())
2. @manf Тогда я получу
Monolt;Listlt;Monolt;Outputgt;gt;gt;
. Мне нужно простоMonolt;Listlt;Outputgt;gt;
вместо этого. Добавлен подход, который я уже пробовал.3. @manf Я не хочу блокировать.
Ответ №1:
Если вам по какой-либо причине не нужно создавать поток, вы можете создать поток из ваших входных данных, сопоставить его и собрать список
Flux.fromIterable(inputs).flatMap(processor::process).collectList();
Комментарии:
1. Вы можете использовать тот же подход, даже если начнете с
outputs
вместоinputs
(отредактировал мой ответ). Но так будет лучше.
Ответ №2:
// first merge all the `Mono`s: Listlt;Monolt;Outputgt;gt; outputs = ... Fluxlt;Outputgt; merged = Flux.empty(); for (Monolt;Outputgt; out : outputs) { merged = merged.mergeWith(out); } // then collect them return merged.collectList();
или (вдохновленный ответом Александра)
Flux.fromIterable(outputs).flatMap(x -gt; x).collectList();