I have List<Person>
where Person
is as below.
我有列表
class Person {
String personId;
LocalDate date;
String type;
// getters & setters
}
I'm trying to convert this to List<Person>
to Map<String, Map<LocalDate,List<Person>>>
where outer map's key is personId
and inner map's key is date
and I couldn't figure out how to achieve this. Thus far have tried something like below. Open to Java 8 solutions as well.
我试着将它转换为List
Map<String,Map<LocalDate,List<Person>>> outerMap = new HashMap<>();
Map<LocalDate,List<Person>> innerMap = new HashMap<>();
for(Person p : list) {
List<Person> innerList = new ArrayList<>();
innerList.add(p);
innerMap.put(p.getDate(), innerList);
outerMap.put(p.getPersonId(), innerMap);
}
3 个解决方案
#1
16
list.stream()
.collect(Collectors.groupingBy(
Person::getPersonId,
Collectors.groupingBy(
Person::getDate
)));
#2
6
This answer shows how to do it with streams and this other one how to do it with a traditional iterative approach. Here's yet another way:
这个答案显示了如何使用流和另一个方法来使用传统的迭代方法。这里有另一种方法:
Map<String, Map<LocalDate, List<Person>>> outerMap = new HashMap<>();
list.forEach(p -> outerMap
.computeIfAbsent(p.getPersonId(), k -> new HashMap<>()) // returns innerMap
.computeIfAbsent(p.getDate(), k -> new ArrayList<>()) // returns innerList
.add(p)); // adds Person to innerList
This uses Map.computeIfAbsent
to create a new innerMap
and put it in the outerMap
if not present (the key being personId
), and also to create a new innerList
and put it in the innerMap
if not present (the key being date
). Finally, the Person
is added to the innerList
.
它使用Map.computeIfAbsent创建一个新的innerMap,并将其放入到outerMap中,如果不存在(关键是personId),还可以创建一个新的innerList,并将其放入到innerMap中,如果不存在(关键是日期)。最后,将Person添加到innerList中。
#3
3
Your for
loop organization should be changed in such a way that it tries getting an existing List<Person>
from the nested map before proceeding with creation of the new list. This is a two-step process:
您的for循环组织应该以这样的方式进行更改,以便在继续创建新列表之前,从嵌套映射中获取一个已存在的列表
Map<String,Map<LocalDate,List<Person>>> outerMap = new HashMap<>();
for(Person p : list) {
Map<LocalDate,List<Person>> innerMap = outerMap.get(p.getPersonId());
if (innerMap == null) {
innerMap = new HashMap<>();
outerMap.put(p.getPersonId(), innerMap);
}
List<Person> innerList = innerMap.get(p.getDate());
if (innerList == null) {
innerList = new ArrayList<>();
innerMap.put(p.getDate(), innerList);
}
innerList.add(p);
}
#1
16
list.stream()
.collect(Collectors.groupingBy(
Person::getPersonId,
Collectors.groupingBy(
Person::getDate
)));
#2
6
This answer shows how to do it with streams and this other one how to do it with a traditional iterative approach. Here's yet another way:
这个答案显示了如何使用流和另一个方法来使用传统的迭代方法。这里有另一种方法:
Map<String, Map<LocalDate, List<Person>>> outerMap = new HashMap<>();
list.forEach(p -> outerMap
.computeIfAbsent(p.getPersonId(), k -> new HashMap<>()) // returns innerMap
.computeIfAbsent(p.getDate(), k -> new ArrayList<>()) // returns innerList
.add(p)); // adds Person to innerList
This uses Map.computeIfAbsent
to create a new innerMap
and put it in the outerMap
if not present (the key being personId
), and also to create a new innerList
and put it in the innerMap
if not present (the key being date
). Finally, the Person
is added to the innerList
.
它使用Map.computeIfAbsent创建一个新的innerMap,并将其放入到outerMap中,如果不存在(关键是personId),还可以创建一个新的innerList,并将其放入到innerMap中,如果不存在(关键是日期)。最后,将Person添加到innerList中。
#3
3
Your for
loop organization should be changed in such a way that it tries getting an existing List<Person>
from the nested map before proceeding with creation of the new list. This is a two-step process:
您的for循环组织应该以这样的方式进行更改,以便在继续创建新列表之前,从嵌套映射中获取一个已存在的列表
Map<String,Map<LocalDate,List<Person>>> outerMap = new HashMap<>();
for(Person p : list) {
Map<LocalDate,List<Person>> innerMap = outerMap.get(p.getPersonId());
if (innerMap == null) {
innerMap = new HashMap<>();
outerMap.put(p.getPersonId(), innerMap);
}
List<Person> innerList = innerMap.get(p.getDate());
if (innerList == null) {
innerList = new ArrayList<>();
innerMap.put(p.getDate(), innerList);
}
innerList.add(p);
}