【问题标题】:How to sort a HashMap first by value and then by key in case of duplicates? [duplicate]如何在重复的情况下先按值排序 HashMap,然后按键排序? [复制]
【发布时间】:2018-02-15 23:42:52
【问题描述】:

我有一个类似这样的 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)

有什么建议吗?

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

【问题讨论】:

  • 你必须使用 LinkedHashMap - 因为 HashMap 无法维护订单。
  • @AriSingh 并不完全是重复的,因为我相信这个问题存在细微差别。
  • @Aominè 它有什么不同 - 仅仅因为值是重复的?重复值不会改变答案/解决方案。只是比较器必须再做一次检查。

标签: java dictionary hashmap


【解决方案1】:

您可以使用流 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) -&gt; oldValue 是用于解决与同一键关联的值之间的冲突的合并函数。

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


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

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

【讨论】:

  • 喜欢Map.Entry.comparingByValueMap.Entry.comparingByKey的使用。
  • '如何对HashMap 进行排序':停在那里。你不能。
  • @EJP 是的,因此建议将流管道的结果累积到 LinkedHashMap 实例中。
猜你喜欢
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 2016-11-03
  • 2021-09-13
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
相关资源
最近更新 更多