我有List<Person>
,其中Person
如下所示。
class Person {
String personId;
LocalDate date;
String type;
// getters & setters
}
我正在尝试将此转换为List<Person>
到Map<String, Map<LocalDate,List<Person>>>
,其中外部地图的键为personId
,内部地图的键为date
,我无法弄清楚如何为达到这个。
到目前为止,尝试过如下所示的内容也可以使用Java 8解决方案。
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);
}
答案 0 :(得分:17)
list.stream()
.collect(Collectors.groupingBy(
Person::getPersonId,
Collectors.groupingBy(
Person::getDate
)));
答案 1 :(得分:7)
This answer展示了如何使用流和this other one如何使用传统的迭代方法来实现它。这是另一种方式:
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
这会使用Map.computeIfAbsent
创建新的innerMap
并将其放入outerMap
(如果不存在)(密钥为personId
),并创建新的innerList
{1}}并将其放入innerMap
(如果不存在)(密钥为date
)。最后,Person
已添加到innerList
。
答案 2 :(得分:3)
应该更改您的for
循环组织,使其在继续创建新列表之前尝试从嵌套映射中获取现有List<Person>
。这是一个两步过程:
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);
}