2014-12-12 29 views
9

Mam następujący obiekt i mapę:Java 8 strumienie: iteracyjne nad mapą of Lists

MyObject 
    String name; 
    Long priority; 
    foo bar; 

Map<String, List<MyObject>> anotherHashMap; 

chcę przekonwertować mapę w innej mapy. Klucz mapy wyników jest kluczem mapy wejściowej. Wartość mapy wyników stanowi właściwość "nazwa" obiektu My, uporządkowana według priorytetu.

Zamówienie zamawianie i wyodrębnianie nazwy nie jest problemem, ale nie mogłem umieścić go na mapie wyników. Robię to starą metodą Java 7, ale byłoby miło, że można korzystać z API do przesyłania strumieniowego.

Map<String, List<String>> result = new HashMap<>(); 
for (String identifier : anotherHashMap.keySet()) { 
    List<String> generatedList = anotherHashMap.get(identifier).stream()...; 

    teaserPerPage.put(identifier, generatedList); 
} 

Czy ktoś ma pomysł? Próbowałem, ale utknął:

anotherHashMap.entrySet().stream().collect(Collectors.asMap(..., ...)); 
+0

Zamysł nie jest jasny. Czy możesz wyjaśnić, co chcesz zrobić? –

+0

Czy to wyjaśnienie jest lepsze? – waXve

+0

Jakie są wartości wynikowych map? Lista każdej "nazwy" z poprzedniego klucza? – mkobit

Odpowiedz

10
Map<String, List<String>> result = anotherHashMap 
    .entrySet().stream()     // Stream over entry set 
    .collect(Collectors.toMap(    // Collect final result map 
     Map.Entry::getKey,     // Key mapping is the same 
     e -> e.getValue().stream()   // Stream over list 
      .sorted(Comparator.comparingLong(MyObject::getPriority)) // Sort by priority 
      .map(MyObject::getName)   // Apply mapping to MyObject 
      .collect(Collectors.toList())) // Collect mapping into list 
     ); 

Zasadniczo strumień nad każdym zestawem wejściowym i zebrać go na nowej mapie. Aby obliczyć wartość na nowej mapie, przesyłasz strumieniowo ponad List<MyOjbect> ze starej mapy, sortuj i stosuj do niej funkcję mapowania i zbierania. W tym przypadku jako mapowanie użyłem MyObject::getName i zebrałem nazwy wynikowe na liście.

1

Do generowania inną mapę, możemy mieć coś jak następujące:

HashMap<String, List<String>> result = anotherHashMap.entrySet().stream().collect(Collectors.toMap(elem -> elem.getKey(), elem -> elem.getValue() // can further process it); 

Nad ja ponownie odtworzyć mapę, ale można przetwarzać klawisz lub wartość według twoich potrzeb.

+0

hmm ... To nie działa. Nie ma metody zbierania na mapie ... – waXve

+0

To powinno być '.stream(). Collect" Wierzę. Również musisz zmapować listę 'MyObject', coś w stylu' elem -> elem.getValue(). Stream(). Map (e -> e.name) ' –

+0

Nie pamiętam, aby dodać metodę entrySet(). to :) –

1
Map<String, List<String>> result = anotherHashMap.entrySet().stream().collect(Collectors.toMap(
    Map.Entry::getKey, 
    e -> e.getValue().stream() 
     .sorted(comparing(MyObject::getPriority)) 
     .map(MyObject::getName) 
     .collect(Collectors.toList()))); 

Podobny odpowiedzieć Mike KOBIT, ale sortowania jest stosowana w odpowiednim miejscu (czyli wartość jest sortowana, nie map wpisy) i bardziej zwięzły sposób statyczny Comparator.comparing jest używana do pobierania komparatora do sortowania.

Powiązane problemy