Home > Enterprise >  Java stream collect to Map<String, Map<Integer, List<MyObject>>>
Java stream collect to Map<String, Map<Integer, List<MyObject>>>

Time:07-08

I'm using java 11 and I have an List of objects called MyObject and it looks like this

public class MyObject {
  private final String personalId;
  private final Integer rowNumber;
  private final String description;
<...>
}

and I want using streams to collect these objects into a Map<String, Map<Integer, List<MyObject>>> (Map<personalId, Map<rowNumber, List<MyObject>>>) and I don't want to use Collectors.groupBy(), because it has issues with null values.

I tried to do it using Collectors.toMap(), but it seems that it is not possible to do it

myList
.stream()
.Collectors.toMap(s -> s.getPersonalId(), s -> Collectors.toMap(t-> s.getRowNumber(), ArrayList::new))

My question is it possible to make a map<String, Map<Integer, List<MyObject>>> object using streams without using Collectors.groupBy() or should I write a full method myself?

CodePudding user response:

In your case I would create the maps first and then loop through the elements in this list as shown:

Map<String, List<MyObject>> rows = new HashMap<>(); 
list.forEach(element -> rows.getOrDefault(element.rowNumber, new ArrayList<MyObject>()).add(element));

You can use getOrAddDefault in order to create a new list/map as a value of the map before you can put your data in.


The same is with the second data type you created:

Map<String, Map<Integer, MyObject>> persons = new HashMap<>();
list.forEach(element -> persons.getOrDefault(element.personalId, new HashMap<>()).put(element.rowNumber, element));

Here is a way to solve this with streams:

Map<String, List<MyObject>> rows = list.stream().collect(
        Collectors.toMap(element -> element.personalId, 
        element -> new ArrayList<MyObject>(Arrays.asList(element))));

As well as for the other map:

    Map<String, Map<Integer, MyObject>> persons = list.stream().collect(
            Collectors.toMap(e -> e.personalId, 
            e -> new HashMap<>(Map.of(e.rowNumber, e))));
  •  Tags:  
  • java
  • Related