如何先按值对HashMap进行排序,然后在重复的情况下按键进行排序?

时间:2018-02-15 23:42:52

标签: java dictionary hashmap

我有一个类似的HashMap:

 HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
 map.put(3, 2);
 map.put(7, 2);
 map.put(5, 1);
 map.put(10, 4);

我需要先按值排序,然后按键排序,以防多个键共享相同的值。

结果应如下所示:

(5, 1)
(3, 2)
(7, 2)
(10, 4)

有什么建议吗?

我只是在重复值的情况下比较第一个值和键。所以我使用了键和值,而不仅仅是值。

1 个答案:

答案 0 :(得分:3)

您可以使用流API实现它:

LinkedHashMap<Integer, Integer> resultSet = 
  map.entrySet().stream()
                .sorted(Map.Entry.<Integer, Integer>comparingByValue()
                             .thenComparing(Map.Entry.comparingByKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));

sorted中间操作可以采用Comparator实例,在这种情况下是:

Map.Entry.<Integer, Integer>comparingByValue()
                                 .thenComparing(Map.Entry.comparingByKey())

即。按地图值进行比较,如果两个给定值相同,则按键进行比较。

继续collect终端操作:

Map.Entry::getKeykeyMapper,它是用于生成地图密钥的映射函数。

Map.Entry::getValuevalueMapper,它是用于生成地图值的映射函数。

(oldValue, newValue) -> oldValue是用于解决与同一密钥关联的值之间的冲突的合并函数。

LinkedHashMap::new提供了一个新的空Map,结果将插入其中。我们在此处指定了LinkedHashMap以维持广告订单。

注意合并函数(oldValue, newValue) -> oldValue在这种情况下是没有意义的,因为流的源(map.entrySet())永远不会包含重复的键。但是,我们仍然需要它,否则我们不能为新值指定累加器的类型,在这种情况下,是LinkedHashMap实例来维护插入顺序。

您可能还想查看toMap方法,以获取有关其工作原理的更多信息。