[英]Sorting problem using TreeMap
我正在嘗試在HashMap中放置一些鍵值,然后嘗試使用TreeMap進行排序,如下所示。 問題是如果地圖中有類似的值,那么在排序后它會考慮其中任何一個。
import java.util.*;
public class HashmapExample {
public static void main(String[] args) {
HashMap<String,Integer> map = new HashMap<String,Integer>();
ValueComparator bvc = new ValueComparator(map);
TreeMap<String,Integer> sorted_map = new TreeMap(bvc);
map.put("A",99);
map.put("B",67);
map.put("C",123);
map.put("G",67);
map.put("F",67);
map.put("H",67);
map.put("D",6);
System.out.println("unsorted map");
for (String key : map.keySet()) {
System.out.println("key/value: " + key + "/"+map.get(key));
}
sorted_map.putAll(map);
System.out.println("results after sorting");
for (String key : sorted_map.keySet()) {
System.out.println("key/value: " + key + "/"+sorted_map.get(key));
}
}
}
class ValueComparator implements Comparator {
Map base;
public ValueComparator(Map base) {
this.base = base;
}
public int compare(Object a,Object b) {
if((Integer)base.get(a) > (Integer)base.get(b)) {
return 1;
} else if((Integer)base.get(a) == (Integer)base.get(b)) {
return 0;
} else {
return -1;
}
}
}
在此之后輸出如下
unsorted map
key/value: D/6
key/value: A/99
key/value: F/67
key/value: H/67
key/value: C/123
key/value: B/67
key/value: G/67
results after sorting
key/value: D/6
key/value: F/67
key/value: A/99
key/value: C/123
對於B,G,F和H鍵,我給出值為67.在排序映射之后,它僅顯示F值並且消除B,G和H值。 我想顯示下面的輸出
key/value: D/6
key/value: B/67
key/value: G/67
key/value: F/67
key/value: H/67
key/value: A/99
key/value: C/123
鍵B,G和H被消除的原因是因為您提供的比較器僅基於值進行比較。 由於它們都具有相同的值,因此它們都是相等的鍵,這意味着將覆蓋其他鍵。
要打印出你想要的東西,比較器需要首先比較這些值,然后如果它們相等,則比較這些鍵。
int compare(Comparable key1, Comparable key2) {
// I'm guessing you are doing something like:
// return map.get(key1).compareTo(map.get(key2));
// you can change it to something like
int result = key1.compareTo(key2);
if ( result == 0 ) {
result= key1.compareTo(key2)
}
return result;
}
不要為此目的使用TreeSet或使smt像
class ValueComparator implements Comparator<String> {
private final Map<String, Integer> base;
public ValueComparator(Map<String, Integer> base) {
this.base = base;
}
public int compare(String a, String b) {
int compareInts = base.get(a).compareTo(base.get(b));
if (compareInts == 0) {
return a.compareTo(b);
} else {
return compareInts;
}
}
}
TreeSet刪除重復項,即compareTo()== 0時。
我建議你讓比較器在值相同時比較鍵,你應該得到。
key/value: D/6
key/value: B/67
key/value: F/67
key/value: G/67
key/value: H/67
key/value: A/99
key/value: C/123
眾所周知,你的比較代碼已被破壞。 用它替換它。 這不會考慮具有相同值的兩對,但是不同的鍵,相等。
public int compare(Object a,Object b) {
if((Integer)base.get(a) > (Integer)base.get(b)) {
return 1;
} else if((Integer)base.get(a) == (Integer)base.get(b)) {
return ((String)a).compareTo((String)b);
} else {
return -1;
}
}
根據傑夫的回答,我寫了一個通用版本:
public class MapValueComparator<K extends Comparable<K>, V extends Comparable<V>> implements Comparator<K> {
private final Map<K, V> base;
private final boolean ascending;
public MapValueComparator(Map<K, V> base) {
this.base = base;
this.ascending = true;
}
public MapValueComparator(Map<K, V> base, boolean ascending) {
this.base = base;
this.ascending = ascending;
}
@Override
public int compare(K a, K b) {
int r = base.get(a).compareTo(base.get(b));
if (r == 0)
r = a.compareTo(b);
if (ascending)
return r;
else
return -r;
}
}
它可以使用如下:
Map<String,Integer> map = new HashMap<String,Integer>();
// add some contents to map ...
MapValueComparator<String, Integer> mvc = new MapValueComparator<String, Integer>(map);
TreeMap<String, Integer> sorted_map = new TreeMap<String, Integer>(mvc);
sorted_map.putAll(map);
您的比較器有問題。 例如,比較方法為G和F返回0.因此樹圖沒有與其中一個相關聯的鍵值對。
你需要研究比較器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.