基于多个值对地图进行排序(Java8/Jooq)

Posted

技术标签:

【中文标题】基于多个值对地图进行排序(Java8/Jooq)【英文标题】:Sorting a map based on multiple values(Java8/Jooq) 【发布时间】:2019-04-13 05:58:23 【问题描述】:

我们有一个看起来像这样的数据结构:

Map<String, Double> responseMap;

并根据值按降序对该地图进行排序:

responseMap.entrySet().stream()
        .sorted((Map.Entry.<String, Double>comparingByValue().reversed()))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, 
                                      (e1, e2) -> e1, LinkedHashMap::new));

现在这张地图的数据结构变成了这样的:

Map<String, Tuple2<Double, Integer> responseMap;  //org.jooq.lambda.tuple.Tuple2

我们如何根据新值(基于 Double 值和 Integer)干净地对该映射进行排序?

【问题讨论】:

【参考方案1】:

你应该简单地改变比较器:

responseMap.entrySet().stream()
    .sorted(Comparator.comparing((Map.Entry<String, Tuple2<Double, Integer> e) -> 
                                  e.getValue().v1())
                      .thenComparing(e -> e.getValue().v2())
                      .reversed())
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, 
                                  (e1, e2) -> e1, LinkedHashMap::new));

编辑(根据 cmets):

或者,您也可以使用:

responseMap.entrySet().stream()
    .sorted(Comparator.comparing(Collections.reverseOrder(Map.Entry.comparingByValue(
            Comparator.comparing(Tuple2::v1).thenComparing(Tuple2::v2)))))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, 
                                  (e1, e2) -> e1, LinkedHashMap::new));

【讨论】:

由于类型推断有限,这将不起作用。您必须为第一个比较器函数提供显式类型,即Comparator.comparing((Map.Entry&lt;String, Tuple2&lt;Double, Integer&gt; e) -&gt; e.getValue().v1()) .thenComparing(e -&gt; e.getValue().v2()) .reversed()。或者,您可以用嵌套调用替换链接的方法调用,即Collections.reverseOrder( Map.Entry.comparingByValue(Comparator.comparing(Tuple2::v1).thenComparing(Tuple2::v2))) @Holger 谢谢,已修复

以上是关于基于多个值对地图进行排序(Java8/Jooq)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中按值对地图进行排序?

在Java中按键或值对地图进行排序[重复]

根据另一个地图中的值对Java Map进行排序

按键和值对地图排序

如何按值对 STL 映射进行排序?

java 根据其值对地图进行排序。资料来源:http://stackoverflow.com/a/2581754/1057348