[英]Sorting map based on list values
I have a map like below: 我有下面的地图:
Map<String, String> map1 = new HashMap<String, String>();
and the contents are: 内容是:
ID_1 -> ID_2
------------
100 -> 10
200 -> 20
300 -> 30
Based on the value of ID_2 I have to query an oracle table and get a code value corresponding to each entry: 基于ID_2的值,我必须查询一个oracle表并获取与每个条目相对应的代码值:
ID_1 -> ID_2 -> code
--------------------
100 -> 10 -> 8
200 -> 20 -> 2
300 -> 30 -> 9
and then I will have to get the map1 sorted in ascending way by the code value ie the result should be: 然后我将不得不按代码值升序对map1进行排序,即结果应为:
200 -> 20
100 -> 10
300 -> 30
I have thought of creating an intermediary map with <ID_1, List<ID_2,code>>
as <K,V>
and then sort using the code value and then get the final output. 我曾考虑过创建一个中间映射,其中<ID_1, List<ID_2,code>>
为<K,V>
,然后使用代码值进行排序,然后得到最终输出。
Is there any shorter way to do so, like without using an intermediary map? 有没有更短的方法,例如不使用中介地图?
You try this code below: I used int[]
array instead of List
您可以在下面尝试以下代码:我使用int[]
数组而不是List
public class Test {
public static void main(String[] args) throws Exception {
Map<String, int[]> map = new HashMap<>();
map.put("100", new int[]{10, 8});
map.put("200", new int[]{20, 2});
map.put("300", new int[]{30, 9});
Map<String, int[]> sortByValue = sortByValue(map);
for (Map.Entry<String, int[]> entry : sortByValue.entrySet()) {
System.out.println(entry.getKey() +" -> "+ entry.getValue()[0]);
}
}
private static Map<String, int[]> sortByValue( Map<String, int[]> map ) {
List<Map.Entry<String, int[]>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, (o1, o2) -> Integer.compare(o1.getValue()[1], o2.getValue()[1]));
Map<String, int[]> result = new LinkedHashMap<>();
for (Map.Entry<String, int[]> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
}
And it is the result: 结果是:
200 -> 20
100 -> 10
300 -> 30
Based on map1 you can build new map: 基于map1,您可以构建新地图:
Map<String, Pair<String, String> map2
where key is id from oracle db. 其中键是来自oracle db的ID。
As you need to have ordering you can use TreeMap and method 需要订购时,可以使用TreeMap和method
Map.Entry<K,V> firstEntry();
I would express you logic as follow : 我将向您表达以下逻辑:
It is important to notice that few maps have ordering constraints. 重要的是要注意,很少有地图具有排序约束。 The base implementation that comes to mind is LinkedHashMap. 我想到的基本实现是LinkedHashMap。 Furthermore "reordering an existing map" seems like a strange idea that is not backed by any methods in the Map
interface . 此外,“对现有地图进行重新排序”似乎是一个奇怪的想法, Map
接口中的任何方法均未对此进行支持。 So in a nutshell, saying you need to return a Map
that has an ordering constraint seems like a bad/incomplete idea - but it is certainly doable. 简而言之,说您需要返回一个具有排序约束的Map
似乎是一个不好的/不完整的想法-但这当然是可行的。
I would also adivse against using a TreeMap
which is a Map ordered by a Comparator
because I see no constraint that your ordering values are unique. 我也反对使用TreeMap
,它是由Comparator
排序的Map,因为我没有看到您的排序值唯一的约束。 Plus, your ordering is on the values, not the keys, of the map. 另外,您的订购取决于地图的值,而不是键。 Such a comparator would not be straightforward at all. 这样的比较器根本不是简单的。
So, in short, what I would do is 简而言之,我要做的是
LinkedHashMap<String, String> sorted = map.entrySet().stream()
// This is your DB call
.sorted(Comparator.comparing(entry -> getDBValue(entry)))
// Now we have an ordered stream of key/value entries from the original map
.collect(
// We flush back to a Map
Collectors.toMap(
// Keeping the original keys as is
Map.Entry::getKey,
// Keeping the original values as is
Map.Entry::getValue,
// This merge step should never be called, as keys are unique. Maybe you could assert that and fail if this is called
(v1, v2) -> v1,
// This is where you instanciate the Map that respects ordering of keys. Here, LinkedHashMap is iterable in the order of insertion, which is what we want.
LinkedHashMap::new
)
);
With Java streams you can achieve this without using any additional collections, here is an implementation. 使用Java流,您可以在不使用任何其他集合的情况下实现此目的,这是一个实现。
To maintain order have used LinkedHashMap
in the collector 为了保持秩序,在收集器中使用了LinkedHashMap
For simplicity I have taken one more map to hold the db values [you need to change this to get from DB] 为简单起见,我又制作了一张地图来保存db值[您需要更改此值才能从DB中获取]
Map<String, String> map1 = new HashMap<String, String>();
map1.put("100", "10");
map1.put("200", "20");
map1.put("300", "30");
Map<String, String> dbmap = new HashMap<String, String>();
dbmap.put("10", "8");
dbmap.put("20", "2");
dbmap.put("30", "9");
Comparator<String> comp = (k1, k2) -> dbmap.get(map1.get(k1)).compareTo(dbmap.get(map1.get(k2)));
Map<String, String> queryMap = map1.keySet().stream().sorted(comp)
.collect(toMap((String key) -> key, value -> (String) map1.get(value), (u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
}, LinkedHashMap::new));
System.out.println(queryMap);
Ouput 乌普特
{200=20, 100=10, 300=30}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.