Как создать моно <карта <карта <List>> из Flux - PullRequest
0 голосов
/ 05 мая 2018

У меня есть форма ответа ниже ответов как Flux.<Response>fromIterable(responses). Я хочу преобразовать это в моно карты следующим образом:

Mono

>>> collectMap =?

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

List< Response> responses = new ArrayList(){
            {
                add(Response.builder().company("Samsung").category("Tab").price("$2000").itemName("Note").build());
                add(Response.builder().company("Samsung").category("Phone").price("$2000").itemName("S9").build());
                add(Response.builder().company("Samsung").category("Phone").price("$1000").itemName("S8").build());
                add(Response.builder().company("Iphone").category("Phone").price("$5000").itemName("Iphone8").build());
                add(Response.builder().company("Iphone").category("Tab").price("$5000").itemName("Tab").build());
            }
        };

Хотя я могу получить начальную карту следующим образом

Mono<Map<String, Collection<Response>>> collect = Flux.<Response>fromIterable( responses )
                .collectMultimap( Response::getCompany );

У кого-нибудь есть идея, как мне достичь своей цели здесь.

1 Ответ

0 голосов
/ 07 мая 2018

Я не думаю, что collectMultiMap или collectMap поможет вам напрямую в этом случае:

  1. Только collectMultiMap (и его перегрузки) может вернуть Map<T, Collection<V>, что явно отличается от того, что вы хотите. Конечно, вы можете обработать результирующий набор значений (а именно, часть карты Collection<V>) со сложностью O (n).

  2. С другой стороны, collectMap (и его перегрузки) выглядят несколько более многообещающе, если вы предоставите функцию значения. Однако у вас нет доступа к другим V объектам, что запрещает вам строить Collection<V>.

Решение, которое я придумал, использует reduce; хотя тип возвращаемого значения: Mono<Map<String, Map<String, List<Response>>>> (помните List<V> вместо Collection<V>)

return Flux.<Response>fromIterable( responses )
           .reduce(new HashMap<>(), (map, user) -> {
                map.getOrDefault(user.getId(), new HashMap<>())
                        .getOrDefault(user.getEmail(), new ArrayList<>())
                        .add(user);
                return map;
            });

Полный тип для HashMap в reduce равен HashMap<String, Map<String, List<AppUser>>>, к счастью, Java может вывести его из возвращаемого типа метода или типа присвоенной переменной.

...