[英]Sorting map based on list values
我有下面的地圖:
Map<String, String> map1 = new HashMap<String, String>();
內容是:
ID_1 -> ID_2
------------
100 -> 10
200 -> 20
300 -> 30
基於ID_2的值,我必須查詢一個oracle表並獲取與每個條目相對應的代碼值:
ID_1 -> ID_2 -> code
--------------------
100 -> 10 -> 8
200 -> 20 -> 2
300 -> 30 -> 9
然后我將不得不按代碼值升序對map1進行排序,即結果應為:
200 -> 20
100 -> 10
300 -> 30
我曾考慮過創建一個中間映射,其中<ID_1, List<ID_2,code>>
為<K,V>
,然后使用代碼值進行排序,然后得到最終輸出。
有沒有更短的方法,例如不使用中介地圖?
您可以在下面嘗試以下代碼:我使用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;
}
}
結果是:
200 -> 20
100 -> 10
300 -> 30
基於map1,您可以構建新地圖:
Map<String, Pair<String, String> map2
其中鍵是來自oracle db的ID。
需要訂購時,可以使用TreeMap和method
Map.Entry<K,V> firstEntry();
我將向您表達以下邏輯:
重要的是要注意,很少有地圖具有排序約束。 我想到的基本實現是LinkedHashMap。 此外,“對現有地圖進行重新排序”似乎是一個奇怪的想法, Map
接口中的任何方法均未對此進行支持。 簡而言之,說您需要返回一個具有排序約束的Map
似乎是一個不好的/不完整的想法-但這當然是可行的。
我也反對使用TreeMap
,它是由Comparator
排序的Map,因為我沒有看到您的排序值唯一的約束。 另外,您的訂購取決於地圖的值,而不是鍵。 這樣的比較器根本不是簡單的。
簡而言之,我要做的是
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
)
);
使用Java流,您可以在不使用任何其他集合的情況下實現此目的,這是一個實現。
為了保持秩序,在收集器中使用了LinkedHashMap
為簡單起見,我又制作了一張地圖來保存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);
烏普特
{200=20, 100=10, 300=30}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.