[英]TreeMap Customized Comparator
所以我想使用帶有自定義比較器的 TreeMap 我的鍵是一個 String: id,我的值是一個 int: count; 我需要比較計數,作為 TREEMAP 中的值(整數)所以我有:
在一節課中:
import java.util.*;
public TreeMap<String, Integer> tm = new TreeMap<String, Integer>(new SortIdCount<Integer>());
在另一堂課中:
import java.util.Comparator;
public class SortIdCount implements Comparator<Integer>{
public int compare(Integer count1, Integer count2) {
return count1.compareTo(count2);
}
}
它在 Eclipse 中顯示錯誤:
The type SortIdCount is not generic; it cannot be parameterized with arguments <Integer>
SortIdCount 類型不是通用的; 它不能用參數參數化<整數>
原因:類SortIdCount
不是通用類型,因此您無法傳遞參數化參數。 行錯誤:( (new SortIdCount<Integer>()
注意:TreeMap 總是根據其鍵進行排序,但是如果您想根據其值對其進行排序,那么您可以使用比較器構建一個邏輯來執行此操作。 以下是按值對 TreeMap 進行排序的完整代碼。
對值進行排序您可以參考以下代碼片段。
import java.util.*;
public class TreeMapDemo {
//Method for sorting the TreeMap based on values
public static <K, V extends Comparable<V>> Map<K, V>
sortByValues(final Map<K, V> map) {
Comparator<K> valueComparator =
new Comparator<K>() {
public int compare(K k1, K k2) {
int compare =
map.get(k1).compareTo(map.get(k2));
if (compare == 0)
return 1;
else
return compare;
}
};
Map<K, V> sortedByValues =
new TreeMap<>(valueComparator);
sortedByValues.putAll(map);
return sortedByValues;
}
public static void main(String args[]) {
TreeMap<String, Integer> treemap = new TreeMap<>();
// Put elements to the map
treemap.put("Key1", 5);
treemap.put("Key2", 4);
treemap.put("Key3", 3);
treemap.put("Key4", 2);
treemap.put("Key5", 1);
// Calling the method sortByvalues
Map sortedMap = sortByValues(treemap);
// Get a set of the entries on the sorted map
Set set = sortedMap.entrySet();
// Get an iterator
Iterator i = set.iterator();
// Display elements
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
}
}
有關更多詳細信息,請參閱此答案
正如其他人可能已經提到的那樣, TreeMap 構造函數中使用的Comparator
用於按key對地圖進行排序。
public TreeMap(比較器比較器)
...根據給定的比較器排序。 插入到映射中的所有鍵必須通過給定的比較器相互比較:comparator.compare(k1, k2) 不能為映射中的任何鍵 k1 和 k2 拋出 ClassCastException...
但是如果你想按value對地圖進行排序,我們仍然有一個使用LinkedHashMap
的解決方案:
Map<String, Integer> treeMap = new TreeMap<>();
treeMap.put("hi", 1);
treeMap.put("there", 3);
treeMap.put("hey", 2);
treeMap = treeMap.entrySet().stream().sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldV, newV) -> oldV, LinkedHashMap::new));
System.out.println(treeMap);
輸出:
{there=3, hey=2, hi=1}
您不能擁有按值排序的TreeMap
。 按值對地圖進行排序的方法有很多,但我相信 TreeMap 不適合那個。 如果您查看 TreeMap 構造函數: TreeMap(Comparator<? super K> comparator)
它將比較器作為參數,它的泛型類型顯然應該是super of Key of the Map
的super of Key of the Map
。 所以當鍵是String
時,不可能發送Comparator<Integer>
。
請按照按值對 Map 進行排序的答案進行操作。
用於 TreeMap 的比較器必須比較鍵,而不是值。
因此,比較必須采用傳遞的鍵並在地圖中查找值。 你有一個經典的母雞(地圖)和雞蛋(比較器)問題。 您需要比較器來創建地圖,但由於比較器必須查看地圖,因此您需要比較器的地圖。 您可以通過在創建comparator.setMap(map)
后使用comparator.setMap(map)
來解決此問題。
但最關鍵的問題是,您的地圖將無法使用。 只要條目未寫入地圖,您就沒有該值,因此比較器將無法工作。 我唯一的想法是使用兩張地圖。 字符串,整數。 第一個僅用於比較器中的查找。 所以你總是必須先放入第一個,然后再放入第二個。
然后你仍然有問題,因為你可能很容易違反SortedMap
契約。 將鍵插入映射后,不得更改(關於排序)。 但是一旦你輸入另一個值,你就會對鍵進行不同的排序。
所以我真的會重新考慮您的要求以及 TreeMap 是否是您需要的最佳解決方案。
public class SortIdCount implements Comparator<String> {
public int compare(String count1, String count2) {
return count1.compareTo(count2);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.