列出<object>到Map <string,map <string,list <object =“”>&gt;&gt;

时间:2018-04-12 14:45:09

标签: java list collections java-8 hashmap

我有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);
}

3 个答案:

答案 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);
}