2011-02-17 58 views
3

我想把一些關鍵值放在HashMap中,然後嘗試使用TreeMap進行分類,如下所示。問題是如果地圖中有相似的值,那麼在排序之後它正在考慮其中的任何一個。使用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值和eleminating乙後, G和H值。我想顯示outputsomething像下面

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 

回答

4

原因鍵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; 

} 
1

一個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 
2

不要使用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; 
     } 
    } 
} 
+0

如果我不喜歡((整數)base.get( a)>(整數)base.get(b))?1:-1; 然後顯示爲NULL的值 – JavaGeek 2011-02-17 20:31:32

+0

@Sukumar Ramadugu,我編輯了一些「正確」的答案) – 2011-02-17 20:38:22

0

你比較有問題。例如比較方法爲G和F返回0。因此,treemap不具有與其中一個關聯值關聯的鍵值對。

您需要使用比較器。

1

大家都說過你的比較代碼壞了。用這個替換它。這不會考慮具有相同值的兩對,但不同的鍵相同。

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; 
    } 

    } 
0

基於傑夫的回答,我寫了一個通用版本:

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);