简体   繁体   中英

How To Generate Mono<Map<Map<List>> from Flux

I have a flux of response form below responses as Flux.<Response>fromIterable(responses) . I want to convert this to Mono of map as follows:

Mono< Map< String, Map< String, Collection< Response>>>> collectMap = ?

where company is first key for which another map of response will be generated with category as key.

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

Though I am able to achieve initial map as follow

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

Do someone has an idea how I can achieve my goal here.

I don't think collectMultiMap or collectMap helps you directly in this case:

  1. The collectMultiMap (and its overloads) only can return Map<T, Collection<V> which is clearly different than what you want. Of course, you can process the resulting value set (namely the Collection<V> part of the map) with a O(n) complexity.

  2. On the other hand collectMap (and its overloads) look a bit more promising, if you provide the value function. However, you don't have access to other V objects, which forbids you to build the Collection<V> .

The solution I came up with is using reduce ; though the return type is: Mono<Map<String, Map<String, List<Response>>>> (mind the List<V> instead of 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;
            });

The full type for the HashMap in reduce is HashMap<String, Map<String, List<AppUser>>> , thankfully Java can deduce that from the return type of the method or the type of the assigned variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM