2017-09-01 43 views
0

我有一個嵌套的以下類型的地圖LinkedHashMap<String, LinkedHashMap<String, ArrayList<Commit>>>。第一張地圖的關鍵字存儲了一些用戶名,第二張地圖的關鍵字是用戶的存儲庫名稱,在ArrayList裏面我有一個對象,具有一些屬性,如散列,消息,附加等等。按照第一張地圖的關鍵字和第二張地圖的關鍵字按字母順序排列整個集合,我如何在同一類型的新集合(對象保持不變)中收集(保存)我的嵌套地圖?Java 8:如何排序和收集兩個內嵌ArrayList的嵌套地圖?

我需要使用lambda和Stream API來做到這一點。這是我想做到這一點的方式:

LinkedHashMap<String, LinkedHashMap<String, ArrayList<Commit>>> sorted = gitUsers.entrySet() 
      .stream() 
      .sorted((u1, u2) -> u1.getKey().compareTo(u2.getKey())) 
      .map(u -> u.getValue() 
        .entrySet() 
        .stream() 
        .sorted((r1, r2) -> collator.compare(r1.getKey(), r2.getKey()))) 
      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(a, b) -> a, LinkedHashMap::new)); 

我肯定做錯了什麼,因爲我不斷收到以下信息:「非靜態方法不能從靜態上下文中引用」,不能收集地圖。我想我無法成功組裝我的地圖,因爲.map()函數和我用過的第二個流。

我知道你會建議我使用TreeMap或排序集合,並在我的lambda中使用.foreach()方法立即打印它(我已經這樣做了),但我需要像這樣完成我已經在上面描述過。

爲了我的編程基礎課程的目的,這個問題應該以這種方式解決。希望你的幫助!

P.S.我一直在尋找解決方案很長一段時間,並且到處研究包括Stack Overflow論壇,並沒有找到任何相應的解決問題的方法。

+0

gitUsers.entrySet()返回什麼類型? – Kostiantyn

+0

gitUsers是以下類型的映射:LinkedHashMap >> gitUsers = new LinkedHashMap <>();'正如我在文章開頭提到的那樣。它是我通過第一個Map的鍵和第二個嵌套Map的鍵排序的初始Map,現在我想收集它 - 兩個具有ArrayList的地圖都收集到相同類型的Map中。 –

+0

請參閱我的回答。我也建議你重命名你的帖子:*如何做嵌套的地圖排序*或因爲它是更通用的,因爲它是更通用 –

回答

3

你的代碼沒有編譯,甚至我刪除排序未知collator比較。

有效的代碼是:

Map<String, Map<String, List<Commit>>> collect = h.entrySet() 
     .stream() 
     .sorted(Map.Entry.comparingByKey()) 
     .collect(Collectors.toMap(
       Map.Entry::getKey, 
       e -> e.getValue() 
         .entrySet() 
         .stream() 
         .sorted(Map.Entry.comparingByKey()) 
         .collect(
           Collectors.toMap(
             Map.Entry::getKey, 
             Map.Entry::getValue, 
             (a, b) -> a, 
             LinkedHashMap::new 
           ) 
         ), 
       (a, b) -> a, 
       LinkedHashMap::new 
       ) 
     ); 

請注意,您可以與您的比較,而不是Map.Entry.comparingByKey()取代。

+0

我用'Collat​​or collat​​or = Collat​​or.getInstance();'所以java可以比較像c#那樣的字符串並打印先寫小寫字母再寫大寫字母。我們的開放式裁判系統需要這個測試來解決這個問題,我忘了在我的例子中改變它,對不起。 非常感謝您的回答並更正了代碼!我會立即嘗試,並會寫回你。 –

+0

我犯了一個錯誤。更正了我的答案。現在它確定 –

+0

「我也建議你將你的帖子重新命名爲:如何進行嵌套地圖排序或因爲它更通用而失去作用」,但我的問題是要正確收集它。我會嘗試重新命名我的帖子並更正確地指定問題。 –

0

2美分,我建議你試試EntryStream爲地圖流操作提供StreamEx。這是我的Fork of StreamEx的解決方案。

StreamEx.of(gitUsers).sortedBy(Entry::getKey) 
     .toMap(Entry::getKey, 
       e -> EntryStream.of(e.getValue()).sortedBy(Entry::getKey).toMap(LinkedHashMap::new), 
       () -> new LinkedHashMap<>()); 

對我而言,代碼簡單明瞭,而且更易於理解。順便說一下,我認爲界面始終是首選。對我來說Map<String, Map<String, List<Commit>>>更好。

+0

謝謝你的解決方案!如果我終於成爲開發人員,我會牢記它。 :)我需要一個使用普通Java的解決方案,因爲我們的Judge System,它只能使用標準庫來測試和編譯程序。 –