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

Abd*_*izk 2 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);
Run Code Online (Sandbox Code Playgroud)

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

结果应如下所示:

(5, 1)
(3, 2)
(7, 2)
(10, 4)
Run Code Online (Sandbox Code Playgroud)

请问有什么建议吗?

我首先比较值,仅在出现重复值的情况下才比较键。所以我同时使用键和值,而不仅仅是值。

Ous*_* D. 5

您可以使用流 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));
Run Code Online (Sandbox Code Playgroud)

所述排序中间操作可能需要Comparator在这种情况下是实例:

Map.Entry.<Integer, Integer>comparingByValue()
                                 .thenComparing(Map.Entry.comparingByKey())
Run Code Online (Sandbox Code Playgroud)

即通过映射值进行比较,如果两个给定的值相同,则通过键进行比较。

继续进行collect终端操作:

Map.Entry::getKeykeyMapper生成映射键的映射函数。

Map.Entry::getValuevalueMapper生成映射值的映射函数。

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

LinkedHashMap::new提供一个新的空 Map,结果将插入其中。我们在LinkedHashMap此处指定了一个来维护插入顺序。


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

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

  • 就像使用`Map.Entry.comparingByValue`和`Map.Entry.comparingByKey`。 (2认同)