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))));