按嵌套嵌套数组大小排序嵌套地图

问题描述:

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

您的问题未指定。如果值为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()),这是对于地图值可比较的最微不足道的情况。

希望我没有说明显而易见,但考虑到您提供的信息,我假设您期望.sorted()可以对原始集合进行排序。

因为您正在使用 Stream 原始集合将不会被修改。 .sorted() 返回一个新的集合。使用这个结果。

+1

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

+0

我只是为了在控制台上打印它而对Map进行排序。我不打算以任何方式修改原文。 –

感谢霍尔格我设法找到一些尝试得到妥善解决:什么工作对我来说是

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