Collect List<Object> to Map<String, List<Object>> in Java 8 using stream

akapti :

I am trying to do this iteration using java 8 stream instead of traditional for loop.

I have a List of Object List<Obligation> and the Obligation is having List of String within.

Obligation contains fields like

f1 and f2 of type String,

and

f3 of type List<String>

What I want to achieve is Map<String, List<Obligation>> such that, String used in key of Map is each value present in List<String> from each Obligation within List<Obligation>

This is how the code would look in traditional for loop:

// newly initialized Map
Map<String, List<Obligation>> map = new LinkedHashMap<String, List<Obligation>>();

// assume the list is populated
List<Obligation> obligations = someMethod();

                for(Obligation obligation : obligations) {
                    for(String license : obligation.getLicenseIDs()) {
                        if(map.containsKey(license)) {
                            map.get(license).add(obligation);
                        } else {
                            List<Obligation> list = new ArrayList<Obligation>();
                            list.add(obligation);
                            map.put(license, list);
                        }
                    }
                }
Eran :

Use flatMap to create a stream of pairs of Obligation and license IDs, and then use groupingBy to collect them by license ID.

Map<String, List<Obligation>> map =
    obligations.stream() // Stream<Obligation>
               .flatMap(o -> o.getLicenseIDs()
                              .stream()
                              .map(id -> new SimpleEntry<>(o,id))) // Stream<Map.Entry<Obligation,String>>
               .collect(Collectors.groupingBy(Map.Entry::getValue,
                                              Collectors.mapping(Map.Entry::getKey,
                                                                 Collectors.toList())));

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=125381&siteId=1