如何通过引用另一个HashMap来对HashMap进行排序。

huangapple go评论68阅读模式
英文:

How to sort HashMap by referring another HashMap

问题

我有两个Java中的HashMap

第一个包含一个键和它的值。第二个包含这些键的评估索引(顺序)。我想通过参考第二个HashMap来对第一个HashMap进行排序。

第一个HashMap <key, value>

<"C","ccc">
<"D","ddd">
<"A","aaa">
<"B","bbb">

第二个HashMap <key, value>

<"0","A">
<"1","B">
<"2","C">
<"3","D">

结果应该是

<"A","aaa">
<"B","bbb">
<"C","ccc">
<"D","ddd">

循环遍历这两个HashMap并检查比较键是简单但不高效的。有没有高效的想法?

英文:

I have two HashMap in Java.

First one contains a key and its value. Where second contains an evaluation index (order) of that keys. I want to sort the first map by referring to the second map.

First HashMap &lt;key, value&gt;

&lt;&quot;C&quot;,&quot;ccc&quot;&gt;
&lt;&quot;D&quot;,&quot;ddd&quot;&gt;
&lt;&quot;A&quot;,&quot;aaa&quot;&gt;
&lt;&quot;B&quot;,&quot;bbb&quot;&gt;

Second HashMap &lt;key, value&gt;

&lt;&quot;0&quot;,&quot;A&quot;&gt;
&lt;&quot;1&quot;,&quot;B&quot;&gt;
&lt;&quot;2&quot;,&quot;C&quot;&gt;
&lt;&quot;3&quot;,&quot;D&quot;&gt;

Result should be

&lt;&quot;A&quot;,&quot;aaa&quot;&gt;
&lt;&quot;B&quot;,&quot;bbb&quot;&gt;
&lt;&quot;C&quot;,&quot;ccc&quot;&gt;
&lt;&quot;D&quot;,&quot;ddd&quot;&gt;

Looping this two map and checking comparing keys is simple but not efficient. Any efficient idea?

答案1

得分: 7

You can use Java Stream API. First, sort the second map entrySet by key then map second map's value as key and get first map's value by value of the second map and then collect as LinkedHashMap using Collectors.toMap

secondMap.entrySet().stream()
         .sorted(Comparator.comparing(Map.Entry::getKey))
         .collect(Collectors.toMap(Map.Entry::getValue, k -> firstMap.get(k.getValue()),
                                                          (x, y) -> y, LinkedHashMap::new));

If you use LinkedHashMap/TreeMap ordered by key for the second map then you don't need to sort the keys. See demo here

英文:

You can use Java Stream API. First, sort the second map entrySet by key then map second map's value as key and get first map's value by value of the second map and then collect as LinkedHashMap using Collectors.toMap

secondMap.entrySet().stream()
         .sorted(Comparator.comparing(Map.Entry::getKey))
         .collect(Collectors.toMap(Map.Entry::getValue, k -&gt; firstMap.get(k.getValue()),
                                                          (x, y) -&gt; y, LinkedHashMap::new));

If you use LinkedHashMap/TreeMap ordered by key for the second map then you don't need to sort the keys. See demo here

答案2

得分: 1

首先,HashMap 不是有序集合。HashMap 中的键值对是根据键的 hashCode() 结果的值来排序的。所以我会说你不能在 HashMap 中保持有序的值。

相反,你可以使用 LinkedHashMap,它将按照插入的顺序进行排序。

对于你的解决方案,我会这样做:

HashMap<String, String> firstMap = ...
HashMap<String, String> secondMap = ...
LinkedHashMap<String, String> orderedMap = new LinkedHashMap<>();
for (int i = 0; i < secondMap.size(); ++i) {
   String key = secondMap.get(String.valueOf(i));
   orderedMap.put(key, firstMap.get(key));
}

我没有运行这段代码,但它应该可以工作。

另外,你也可以使用 TreeMap,它是基于键的 Comparable 接口进行排序的。

至于选择使用 TreeMap 还是 LinkedHashMap,取决于你后续如何使用这个映射。在大多数情况下,LinkedHashMap 足够了,但如果你需要,例如,找到某个键的最接近的较大元素,那么 TreeMap 是一个选择。

这里有一些关于 HashMapTreeMap 的比较:
https://stackoverflow.com/questions/2444359/what-is-the-difference-between-a-hashmap-and-a-treemap

英文:

First of all HashMap is not ordered collections. The key-value pairs in HashMap are ordered based on the value of hashCode() result of keys. So I would say you can't keep sorted values in HashMap.

Instead, you can use LinkedHashMap - it will be ordered with order of insertion.

And for your solution, i would do:

HashMap&lt;String, String&gt; firstMap = ...
HashMap&lt;String, String&gt; secondMap = ...
LinkedHashMap&lt;String, String&gt; orderedMap = new LinkedHashMap&lt;&gt;();
for (int i = 0; i &lt; secondMap.size(); ++i) {
   String key = secondMap.get(String.valueOf(i));
   orderedMap.put(key, firstMap.get(key));
}

Did not run this code, but it should work.

Alternatively, you can use TreeMap that is ordered based on Comparable interface of the keys.

And to answer what is better to use - TreeMap or LinkedHashMap - depends on how actually you are using this map later. In most cases LinkedHashMap is enough, although if you need to, for example, get the closest greater element to some key, then TreeMap is a choice.

There are some comparison between HashMap and TreeMap
https://stackoverflow.com/questions/2444359/what-is-the-difference-between-a-hashmap-and-a-treemap

答案3

得分: 0

Traverse the values of secondMap and collect the related key, value set in the map:

Map<String, String> result = secondMap.values().stream()
        .collect(Collectors.toMap(Function.identity(), firstMap::get, (x, y) -> x, LinkedHashMap::new));

Try this:

Map<String, String> firstMap = new HashMap<>();
firstMap.put("C", "ccc");
firstMap.put("D", "ddd");
firstMap.put("A", "aaa");
firstMap.put("B", "bbb");

Map<String, String> secondMap = new HashMap<>();
secondMap.put("0", "A");
secondMap.put("1", "B");
secondMap.put("2", "C");
secondMap.put("3", "D");

Map<String, String> result = secondMap.values().stream()
        .collect(Collectors.toMap(Function.identity(), firstMap::get, (x, y) -> x, LinkedHashMap::new));
System.out.println(result);
英文:

Traverse the values of secondMap and collect the related key, value set in the map:

Map&lt;String, String&gt; result = secondMap.values().stream()
		.collect(Collectors.toMap(Function.identity(), firstMap::get, (x,y)-&gt; x, LinkedHashMap::new));

Try this:

Map&lt;String, String&gt; firstMap = new HashMap&lt;&gt;();
firstMap.put(&quot;C&quot;, &quot;ccc&quot;);
firstMap.put(&quot;D&quot;, &quot;ddd&quot;);
firstMap.put(&quot;A&quot;, &quot;aaa&quot;);
firstMap.put(&quot;B&quot;, &quot;bbb&quot;);

Map&lt;String, String&gt; secondMap = new HashMap&lt;&gt;();
secondMap.put(&quot;0&quot;, &quot;A&quot;);
secondMap.put(&quot;1&quot;, &quot;B&quot;);
secondMap.put(&quot;2&quot;, &quot;C&quot;);
secondMap.put(&quot;3&quot;, &quot;D&quot;);

Map&lt;String, String&gt; result = secondMap.values().stream()
		.collect(Collectors.toMap(Function.identity(), firstMap::get, (x,y)-&gt; x, LinkedHashMap::new));
System.out.println(result);

huangapple
  • 本文由 发表于 2020年8月12日 13:19:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63370261.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定