2015-01-21 5 views
4

Использования Collectors.groupingBy() я могу легко получить Map<Department, List<Person>> - это дает мне все Person объектов, которые являются частью Department:Java 8 новообращенного Map <департамента Список <Person>> к карте <Департамента, Список <String>>

allPersons.stream().collect(Collectors.groupingBy(Person::getDepartment)); 

Теперь я хотел бы преобразовать получившийся «multimap» так, чтобы он содержал имена всех лиц, а не объекты Person.

Одним из способов достижения этой цели является:

final Map<Department, List<String>> newMap = new HashMap<>(); 
personsByDepartmentMap.stream 
    .forEach((d, lp) -> newMap.put(
     d, lp.stream().map(Person::getName).collect(Collectors.toList()))); 

Есть ли способ, чтобы достичь этой цели без использования newMap объекта? Что-то вроде

final Map<Department, List<String>> newMap = 
       personsByDepartmentMap.stream().someBigMagic(); 

ответ

4

Вы можете преобразовать карту, используя

Map<Department, List<String>> result = 
    personsByDepartmentMap.entrySet().stream() 
     .map(e -> new AbstractMap.SimpleImmutableEntry<>(
     e.getKey(), 
     e.getValue().stream().map(Person::getName).collect(Collectors.toList()))) 
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 

Этот код, очевидно, страдает от того, что нет никакого стандартного Pair типа, но вы можете улучшить его с помощью static import с.

(Update :) Как Brian Goetz has shown вы можете обходить его в этом конкретном случае, объединив отображение и сбор в один шаг, например.

Map<Department, List<String>> result =personsByDepartmentMap.entrySet().stream() 
    .collect(Collectors.toMap(
     Map.Entry::getKey, 
     e->e.getValue().stream().map(Person::getName).collect(Collectors.toList()))); 

Однако, я все еще думаю, что легче получить карту из исходного List в одной операции:

Map<Department, List<String>> collect = allPersons.stream() 
    .collect(Collectors.groupingBy(
     Person::getDepartment, 
     Collectors.mapping(Person::getName, Collectors.toList()) 
    )); 

Это тоже выиграет от static import с:

Map<Department, List<String>> collect = allPersons.stream().collect(
    groupingBy(Person::getDepartment, mapping(Person::getName, toList()))); 
6
Map<Dept, List<String>> namesInDept 
    = peopleInDept.entrySet().stream() 
        .collect(toMap(Map.Entry::getKey, 
           e -> e.getValue().stream() 
                .map(Person::getName) 
                .collect(toList())); 
1

I что вам не нужен посредник Map<Person, List<Department>>. Если это так, вы можете сделать все за один шаг:

Map<Department, List<String>> result = allPersons.stream().collect(
    Collectors.groupingBy(Person::getDepartment, 
     Collectors.mapping(Person::getName, Collectors.toList()) 
    ) 
); 
Смежные вопросы