2017-02-14 50 views
10

Próbuję zebrać na ListMultiMap przy użyciu java 8 bez użycia operacji forEach.Zbieraj na ListMultiMapę Guawy przy użyciu strumieni Java 8

Gdybym miał napisać kod w Javie 7, to będzie coś takiego:

ListMultimap<String, String> result = ArrayListMultimap.create(); 
    for(State state: states) { 
     for(City city: state.getCities()) { 
     result.put(state.getName(), city.getName()); 
     } 
    } 

mogę znaleźć w internecie na website, że rozmowy na temat tworzenia własnych kolektorów do wykorzystania w sytuacjach takich jak ta. Użyłem tej implementacji dla kolektora. Potem napisał następujący kod:

 ListMultimap<String, String> result = states 
     .stream() 
     .flatMap(state -> state.getCities().stream() 
      .map(city -> { 
       return new Pair(state, city); 
      })) 
     .map(pair -> { 
      return new Pair(pair.first().getName(), pair.second().getName())); 
     }) 
     .collect(MultiMapCollectors.listMultimap(
        Pair::first, 
        Pair::second 
       ) 
     ); 

jednak na poziomie zbierania, mogę tylko przekazać tylko jeden parametr, i mogę wydawać się znaleźć sposób, aby zdać dwa parametry. Wzorem ze strony internetowej, zrozumiałem, że aby korzystać z obu, muszę przechowywać „parę” w multimapy takie jak:

ArrayListMultimap<String, Pair> testMap = testObjectList.stream().collect(MultiMapCollectors.listMultimap((Pair p) -> p.first().getName())); 

Jednak nie jest to czego szukam, ja chcesz zebrać do ListMultimap używając nazwy państwa i nazwy miasta używając kolektora java 8 (i bez forEach).

Czy ktoś może mi w tym pomóc? Dziękujemy!

+2

Kod pod tym linkiem nie wygląda na dźwięk; Surowe typy, niezaznaczone rzuty i niepotrzebne zmienne typu dla akumulatora. –

+0

Masz rację! Dziękuję za wskazanie tego! Pomyślałem, że to było dobre, ponieważ znalazłem wiele innych witryn z podobnymi implementacjami. Dziękuję Ci ! – codastic

Odpowiedz

1

Ty mógłby utworzyć własny kolektor że (zauważ, że odpowiedź Louisa Wasserman będzie zrobić forEachOrdered wewnętrznie, tak naprawdę nie można uciec foreach wewnętrznie lub zewnętrznie).

ListMultimap<String, String> list = states.collect(Collector.of(ArrayListMultimap::create, (multimap, s) -> { 
     multimap.putAll(s.getName(), s.getCities().stream().map(City::getName).collect(Collectors.toList())); 
    }, (multi1, multi2) -> { 
     multi1.putAll(multi2); 
     return multi1; 
    })); 
+0

Dziękujemy! Szukałem czegoś podobnego do odpowiedzi Louisa Wassermana, ale dałeś mi całkiem niezły pomysł, którego potrzebuję do czegoś innego, mówiąc "Możesz stworzyć niestandardowy kolekcjoner". – codastic