2016-04-26 217 views
0

Hy everyone, 我有按照嵌套數組大小/長度降序排序Java Map的任務,但嵌套數組嵌套在嵌套Map內。該結構是這樣的:按嵌套嵌套數組大小排序嵌套地圖

HashMap<String, HashMap<String, ArrayList<String>>> classes = new HashMap<>(); 

我使用Lambda和我嘗試了許多變化,包括:

classes.entrySet().stream() 
      .sorted((k1, k2) -> Long.compare(classes.get(k2.getKey()).entrySet().stream().count(), classes.get(k1.getKey()).entrySet().stream().count())) 

classes.entrySet().stream() 
      .sorted((k1, k2) -> Integer.compare(k2.getValue().values().size(), k1.getValue().values().size())) 

,但沒有任何運氣。由於數據的性質,我不能使用其他數據結構,所以我必須堅持使用這一數據結構。

任何想法爲什麼我的排序失敗?感謝您的幫助,我很感激。

+1

在是那種沒有什麼意義? –

+0

排序返回嵌套地圖的大小,而不是嵌套地圖內的數組大小。 –

+0

在'classes'映射中有一個鍵與多個數組關聯。您需要彙總長度值。按平均值,總和,中位數排序?你的例子看起來是對'map'的大小進行排序,而不是所包含數組的大小。 – GuiSim

回答

0

您的問題未指定。如果值爲Map,則不能僅僅說您希望按列表的大小進行排序,因爲每個Map中可以有任意數量的列表。你在評論中給出的例子沒有澄清任何事情,因爲它根本沒有解決這個問題。如果你認爲「奴隸」地圖總是有一個大小,你應該明確指定。否則,你必須彙總尺寸。

此外請注意,Comparator接口中有static方法用於根據要比較的元素的屬性創建比較器,因此不需要編寫代碼來提取屬性兩次。

因此,解決辦法總結列表的大小可能看起來像

classes.entrySet().stream() 
    .sorted(Comparator.comparingInt(e -> e.getValue().values() 
              .stream().mapToInt(Collection::size).sum())) 
    .forEach(System.out::println); 

注意,這也聚集作品,如果只有一個在每個「奴隸」的地圖列表。

只要是完整的,請注意,專門爲排序映射條目,也有在Map.Entry界面比較的工廠可以使用像

classes.entrySet().stream() 
    .sorted(Map.Entry.comparingByValue(Comparator.comparingInt(
     m -> m.values().stream().mapToInt(Collection::size).sum()))) 
    .forEach(System.out::println); 

儘管在這種特定的情況下,有在使用它沒有任何益處。但是,如果實際值比較器更簡單,則可能會改善代碼。甚至還有一個無參數變量(即Map.Entry.comparingByValue()),這是對於地圖值可比較的最微不足道的情況。

1

希望我沒有說明顯而易見,但考慮到您提供的信息,我假設您期望.sorted()可以對原始集合進行排序。

因爲您正在使用 Stream 原始集合將不會被修改。 .sorted() 返回一個新的集合。使用這個結果。

+1

那麼它會返回一個排序的'Stream'。它仍然需要收集到一個集合中(支持排序)。 – Kayaman

+0

我只是爲了在控制檯上打印它而對Map進行排序。我不打算以任何方式修改原文。 –

0

感謝霍爾格我設法找到一些嘗試得到妥善解決:什麼工作對我來說是

classes.entrySet().stream() 
      .sorted((k1, k2) -> Integer.compare(k2.getValue().values().stream() 
          .mapToInt(Collection::size).sum(), 
        k1.getValue().values().stream() 
          .mapToInt(Collection::size).sum()))