1

Problem

I have a list of objects like:

Class MyObj {
  private List<Integer> categories;
  private String name;
}

I want to map the list of objects to a Map<Integer, List<MyObj>> using a single stream chain.

Example

MyObj obj1 = new MyObj("name1", Arrays.asList(1, 2, 3));

MyObj obj2 = new MyObj("name2", Arrays.asList(1, 4, 3));

MyObj obj3 = new MyObj("name3", Arrays.asList(4));

List<MyObj> objsList = Arrays.asList(obj1, obj2, obj3);

// Here is what Im trying to accomplish:
// a map like -> **{1: [obj1, obj2], 2: [obj1], 3: [obj1, obj2], 4: [obj2, obj3]}**

Map<Integer, List<MyObj>> = objsList.stream
...help

Looking for a map -> {1: [obj1, obj2], 2: [obj1], 3: [obj1, obj2], 4: [obj2, obj3]}

I think the answer is obvious, but I cant seem to get it to work and having a hard time searching. Thank you in advance

0100Conan0111
  • 53
  • 1
  • 7

1 Answers1

4

You can stream the List from every MyObj and collect Integer and MyObj as pair and then use Collectors.groupingBy

 Map<Integer,List<MyObj>> result = objsList.stream()
            .flatMap(obj->obj.getCategories().stream().map(i-> Map.entry(i,obj)))
            .collect(Collectors.groupingBy(Map.Entry::getKey,Collectors.mapping(Map.Entry::getValue,Collectors.toList())));

Note : Map.entry is from java 9, you can use new AbstractMap.SimpleEntry<Integer, MyObj>(i, obj) for java 8

Naman
  • 27,789
  • 26
  • 218
  • 353
Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98