2017-02-14 28 views
10

我正在嘗試使用java 8收集到ListMultiMap中,而不使用forEach操作。使用Java 8流收集到Guava的ListMultiMap中

如果我是寫在Java 7中的代碼,這將是這樣的:

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

我在網上找到一個website談到有關創建您自己的收藏者在方案中使用,如這一個。 我用這個實現收集器。然後我寫了下面的代碼:

 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 
       ) 
     ); 

但在收集的水平,我只能通過只有一個參數,我似乎可以找到一種方法,傳遞兩個參數。 繼從網站的例子中,我明白了使用這兩種,我需要存儲在多重映射一個「對」,如下列:

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

但是這不是我要找的,我想要使用狀態的名稱和城市的名稱使用java 8的收集器(並且沒有forEach)收集到ListMultimap中。

有人可以幫我嗎? 謝謝!

+2

該鏈接後面的代碼看起來沒有聲音;原始類型,未選中的轉換和累加器不需要的類型變量。 –

+0

你是對的!謝謝你指出! 我認爲這聽起來很合理,因爲我發現了很多其他類似實現的網站。謝謝 ! – codastic

回答

1

可以創建一個自定義的收集器(注意,路易·沃瑟曼的回答會做內部forEachOrdered,你真的不能逃脫一個foreach內部或外部)。

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

謝謝!我正在尋找類似於Louis Wasserman的答案,但是你給了我一個非常好的想法,我需要其他的東西說「你可以創建一個自定義收集器」。 – codastic