简体   繁体   English

如何在 java 8 Stream 中定义自定义排序比较器以比较键和值

[英]How to define custom sorted comparator in java 8 Stream to compare on the key and the value

I want to sort a map using Java 8 streams and return a list of its key.我想使用 Java 8 个流对 map 进行排序并返回其密钥列表。

Map signature is: Map 签名为:

Map<Integer, Integer> ranks = new HashMap<Integer, Integer>();

and the data will be like [ 1=6, 5=13, 2=11 ]数据将类似于 [ 1=6, 5=13, 2=11 ]

There are two conditions on which I have to sort and return a list of keys.有两个条件我必须对键列表进行排序并返回。

  1. If all the values of the keys are different, then sort and return a list based values in descending order, eg如果键的所有值都不同,则按降序排序并返回基于列表的值,例如

    input [1=6, 5=13, 2= 11, 4 = 14 ] result [4,5,2,1]
  2. If two or more values of the key are having same rank, then return these similar in an ascending order, and the rest of the item is in descending order with respect to their values, eg如果 key 的两个或多个 value 具有相同的 rank,则按升序返回这些相似的值,并且 item 的 rest 相对于它们的值按降序排列,例如

    input [2=6, 5=13, 1= 11, 3=13,9 = 22 ] result [9,3,5,1,2]

Below is the code snippet which is working fine for condition 1, but not for condition 2.下面是适用于条件 1 的代码片段,但不适用于条件 2。

List<Integer> ranksList = ranks.entrySet().stream()
    .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
    .map(Map.Entry::getKey)
    .limit(k)
    .collect(Collectors.toList());

Declare the Comparator using thenComparing for chaining.使用thenComparing为链接声明Comparator器。

Comparator<Map.Entry<Integer, Integer>> entryComparator
            = Map.Entry.<Integer, Integer>comparingByValue(Comparator.reverseOrder())
                                         .thenComparing(Map.Entry.comparingByKey());

Map<Integer,Integer> ranks = Map.of(2, 6, 5, 13, 1, 11, 3, 13, 9, 22);

List<Integer> ranksList= ranks.entrySet().stream()
            .sorted(entryComparator)
            .map(Map.Entry::getKey).limit(47)
            .collect(Collectors.toList());

System.out.println(ranksList);

Output is the desired: Output 是所需的:

[9, 3, 5, 1, 2] [9、3、5、1、2]

The type specification <Integer, Integer> of comparingByValue is necessary for Java to infer the types for Map.Entry.comparingByKey() . compareByValue 的类型规范<Integer, Integer>comparingByValue推断Map.Entry.comparingByKey()的类型所必需的。

You are looking for a custom Comparator such as this:您正在寻找这样的自定义Comparator器:

.sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue()) == 0 ?
        o1.getKey().compareTo(o2.getKey()) : o2.getValue().compareTo(o1.getValue()))

Theoretically,理论上,

  • compare the values first in descending order o2.getValue().compareTo(o1.getValue()) and首先按降序比较值o2.getValue().compareTo(o1.getValue())

  • if they are equal compare the keys in the ascending order o1.getKey().compareTo(o2.getKey()) .如果它们相等,则按升序比较键o1.getKey().compareTo(o2.getKey())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM