Reputation: 173
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);
}
}
}
Upvotes: 4
Views: 2881
Reputation: 394126
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())));
Upvotes: 5