如何通过多个属性Java8对HashMap条目值进行排序

Vit*_*lyT 4 java java-8

如何通过多个属性对HashMap条目进行排序.

假设我有一个带有键字符串和值为Object的映射.

Map<String, UserMetrics> map = new HashMap<>
map.put("user10",new UserMetrics(1,100,111));
map.put("user3",new UserMetrics(10,330,444));
map.put("user11",new UserMetrics(333,100,555));
map.put("user1",new UserMetrics(1,111,433));

 public static class UsageMetrics implements Serializable {
        private long param1;
        private long param2;
        private long param3;....
 }
Run Code Online (Sandbox Code Playgroud)

我想先用"param1"排序用户,然后用"param2"排序

结果预期:<>

user10, UserMetrics(1,100,111)
user1,  UserMetrics(1,111,433))
user3,  UserMetrics(10,330,444));
user11, UserMetrics(333,100,555))
Run Code Online (Sandbox Code Playgroud)

lex*_*ore 6

您可以使用以下比较器进行排序:

Comparator
        .comparingLong(UserMetrics::getParam1)
        .thenComparingLong(UserMetrics::getParam2);
Run Code Online (Sandbox Code Playgroud)

然而,困难在于您要对值进行排序,而不是键.你似乎也需要键和值.为此,您可以对地图的条目集进行复制和排序.一些事情:

List<Map.Entry<String, UserMetrics>> sortedEntries = new ArrayList<>(map.entrySet());
Collections.sort(sortedEntries,
    Map.Entry.comparingByValue(
        Comparator
            .comparingLong(UserMetrics::getParam1)
            .thenComparingLong(UserMetrics::getParam2)));
Run Code Online (Sandbox Code Playgroud)

或者,您也可以使用已排序的集合(如TreeSet)或已排序的流 - 通常您可以为"排序事物"提供自己的比较器.

还要注意我正在使用comparingLong/ thenComparingLong,不同于人们刚使用comparing/的其他答案thenComparing.comparing/ 的问题thenComparing在于,如果你有原始类型long,comparing/ thenComparing将基本上将它们装入包装类型Long,这是完全没必要的.