Как отсортировать мульти в smallrye mutiny
Другие реактивные библиотеки, такие как projectactor, предлагают методы сортировки для издателей, но в бунте такого метода нет. В их документации об этом даже не говорится.
Прямо сейчас я достигаю указанной функциональности, делая это
multi.collectItems()
.asList()
.map(
list -> {
list.sort();
return list;
})
.convert()
.with(listUni -> Multi.createFrom().iterable(listUni.await().indefinitely()))
Есть ли лучший способ сделать то же самое?
3 ответа
Я не верю, что есть встроенный / лучший способ сделать это.
Mutiny обычно ценится за наличие "урезанного" набора операторов в своем ядре и за возможность создавать другие, более сложные операторы по мере необходимости. Они пытаются избежать ситуации с реактором, когда вы используете более 100 методов для пары основных типов, и без достаточных базовых знаний часто трудно понять, какие из них актуальны.
ИМХО, это не плохо. В других реактивных фреймворках определенно есть эти встроенные
sort()
операторов, но здесь есть опасность - люди предполагают, что они все еще могут относиться к ним как к бесконечным, волшебным образом отсортированным издателям, потому что нигде нет никаких следов каких-либо коллекций. Вы, конечно, не можете - внутренне эти структуры должны поддерживать базовую коллекцию для сортировки данных, а затем просто выводить ее содержимое, когда поток завершен. Однако это не так ясно, и незнание этого факта часто может привести к непреднамеренному замедлению и
OutOfMemoryError
. Напротив, в вашем примере сразу очевидно, что этот поток использует базовую коллекцию для сортировки ваших данных.
Есть только одна незначительная вещь, которую я бы изменил в вашем примере, но не совсем связанный с вашим вопросом - я бы использовал:
list.stream().sorted().collect(Collectors.toList())
... в вызове карты вместо сортировки изменяемого списка. Мутации структур данных в реактивном потоке - это немного запах кода.
Другой подход, который я использовал, — объединять мульти в TreeMap, как только они приходят с
.collect().in(TREE_MAP_SUPPLIER, MULTI_MAP_ACCUMULATOR)
- Преобразуйте Multi в Uni (список).
- Отсортируйте список из Uni.
- Преобразование Uni в Multi
multi.collect().asList() //1
.onItem()
.transform(list -> list.stream().sorted(Comparator.comparing(item::getId)).toList()) //2
.onItem()
.transformToMulti(list -> Multi.createFrom().iterable(list)); //3