Project reactor, Convert Flux into Map<String,List<Data>>

5.4k Views Asked by At

I have a list of Data object

public class Data{
    private String id;
    private String sharedId;
}

How to convert this list into Map<String,List<Data>>, collecting the data object sharing the same sharedId together

I have tried to use this line of code, but no luck

Map<String,List<Data>> dataMap= Flux.fromIterable(list)
        .collectMap(item-> item.getSharedId(),
                item-> item);
3

There are 3 best solutions below

0
On BEST ANSWER

Stream API is not equal to Reactive API and they are not interchangeable.


Use Stream API for grouping into Map<String, List<Data>> from List<Data>:

Map<String,List<Data>> dataMap = list.stream()
    .collect(Collectors.groupingBy(Data::getSharedId));

Using Reactive API to achieve you achieve Flux<GroupedFlux<String, Data>> analogically or expand the structure using Map.Entry:

Flux<GroupedFlux<String, Data>> groupedFlux = Flux.fromIterable(list)
    .groupBy(Data::getSharedId);
Flux<Map.Entry<String, List<Data>>> groupedFlux = Flux.fromIterable(list)
    .groupBy(Data::getSharedId)
    .flatMap(group -> group
        .collectList()
        .map(listOfData -> Map.entry(group.key(), listOfData)));
0
On

With regards to previous answers from Nikolas & Joao you could also use:

Mono<Map<String, Collection<Data>>> mapCollection = Flux.fromIterable(list)                                       
                                              .collectMultimap(Data::getSharedId, item -> item);

you can map further to specific collection if it needs to be a list:

Mono<Map<String, List<Data>>> mapList = mapCollection
    .map(map -> map
        .entrySet()
        .stream()
        .collect(Collectors.toMap(Entry::getKey, e -> List.copyOf(e.getValue()))))

or use:

Mono<Map<String, List<Data>>> mapList2 = Mono.just(list)
                                         .map(l -> l.stream().collect(Collectors.groupingBy(Data::getSharedId)));
0
On

The following should work:

Map<String,List<Data>> dataMap = 
    list.stream().collect(groupingBy(Data::getSharedId));