Hy大家, 我的任务是按嵌套数组大小/长度的降序排序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()))
但没有任何运气。由于数据的性质,我不能使用其他数据结构,我必须坚持使用这个。
为什么我的排序失败了?感谢您的帮助,我很感激。
答案 0 :(得分:1)
希望我没有陈述显而易见的内容,但鉴于您提供的信息,我假设您希望.sorted()
对原始收藏品进行排序。<\ n / p>
因为您正在使用
Stream
原始系列不会被修改。
.sorted()
返回一个新集合。使用结果。
答案 1 :(得分:0)
您的问题未得到充分说明。如果值为Map
s,则不能仅仅表示您希望按其列表大小排序,因为每个Map
中可以有任意数量的列表。您在评论中给出的示例并未澄清任何内容,因为它根本没有解决该问题。如果您假设“slave”映射的大小始终为1,则应明确指定。否则,您必须汇总大小。
进一步注意static
接口中有Comparator
个方法,用于根据要比较的元素的属性创建比较器,因此您无需编写代码来提取属性两次。
因此,总结列表大小的解决方案可能看起来像
classes.entrySet().stream()
.sorted(Comparator.comparingInt(e -> e.getValue().values()
.stream().mapToInt(Collection::size).sum()))
.forEach(System.out::println);
请注意,如果每个“slave”映射中只有一个列表,则此聚合也可以使用。
为了完整,请注意,专门用于排序地图条目,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()
)。
答案 2 :(得分:0)
感谢Holger,我设法通过更多的实验找到了合适的解决方案:对我有用的是
classes.entrySet().stream()
.sorted((k1, k2) -> Integer.compare(k2.getValue().values().stream()
.mapToInt(Collection::size).sum(),
k1.getValue().values().stream()
.mapToInt(Collection::size).sum()))