2012-01-24 42 views
3

我想對兩個LinkedHashMap的值進行排序。我可以編譯它並運行代碼,但它告訴我在編譯期間使用-Xlint選項,因爲它是不安全的代碼。它與類型轉換的東西有關,但我對如何去做這件事感到非常困惑。我得到這個類,我在班級把inbedded:混淆瞭如何在另一個類中輸入比較器

static class MyComparator implements Comparator { 

     public int compare(Object obj1, Object obj2){ 
      int result=0; 
      Map.Entry e1 = (Map.Entry)obj1 ; 
      Map.Entry e2 = (Map.Entry)obj2 ;//Sort based on values. 

      Integer value1 = (Integer)e1.getValue(); 
      Integer value2 = (Integer)e2.getValue(); 

      if(value1.compareTo(value2)==0){ 

       String word1=(String)e1.getKey(); 
       String word2=(String)e2.getKey(); 

       //Sort String in an alphabetical order 
       result=word1.compareToIgnoreCase(word2); 

      } else { 
       //Sort values in a descending order 
       result=value2.compareTo(value1); 
      } 

      return result; 
     } 

    } 

我試圖調用它與我的功能之一:

ArrayList myArrayList=new ArrayList(this.map_freq_by_date.entrySet()); 
Collections.sort(myArrayList, new MyComparator()); 
Iterator itr=myArrayList.iterator(); 

注:this.map_freq_by_date定義如下:

Map<String,Integer> map_freq_by_date = new LinkedHashMap<String,Integer>(); 

我-Xlint選項得到的錯誤:

unchecked call to ArrayList(java.util.Collection<? extends E>) as a member of the raw type java.util.ArrayList 
ArrayList myArrayList=new ArrayList(this.map_freq_by_date.entrySet()); 


unchecked conversion 
found LogGrep.MyComparator 
required: java.util.Comparator(? super T> 
    Collections.sort(myArrayList, new MyComparator()); 

unchecked method invocation: <T>sort(java.util.List<T>,java.util.Comparator<? super T> in java.util.Collections is applied to (java.util.ArrayList,LogGrep.MyComparator) 
    Collections.sort(myArrayList, new MyComparator()); 

幫助如何解決這些將不勝感激。我在網上查看並嘗試了各種所顯示的內容,但我似乎無法正確理解。

注:如果我把ArrayList<Object> myArrayList = new ArrayList<Object> ...錯誤更改:

unchecked method invocation <T>sort(java.util.List<T>,java.util.Comparator<> super T?) in java.util.Collections is applied ot (java.util.ArraList<java.lang.Object>,LogGrep.MyComparator) 
     Collections.sort(myArrayList, new MyComparator()); 
+0

它沒有列出我map_freq_by_date的定義,我打算在這個問題上面。它被定義爲一個LinkedHashMap 。 – archcutbank

回答

4

比較器是一個通用接口。像這樣做:

static class MyComparator implements Comparator<Map.Entry<String, Integer>> { 
    public int compare(Map.Entry<String, Integer> obj1, Map.Entry<String, Integer> obj2){ 
     ... 
    } 
} 

和定義列表,

List<Map.Entry<String, Integer>> myArrayList = new ArrayList<Map.Entry<String, Integer>>() 

,編譯器會很高興再次。

閱讀the Generics Tutorial瞭解更多信息。或者Angelika Langer's Generics FAQ

順便說一下,除非你比較需要運行參數或者具有可變的狀態,你應該把它定義爲一個常數,而不是每次調用

+0

我剛剛意識到你想要比較地圖條目,而不是整數。在這種情況下,用'Map.Entry '替換所有出現的'Integer'。 –

+0

謝謝!這擺脫了警告。沒有-Xlint選項,沒有更多的警告。如果你知道,使用ArrayList 與ArrayList >有什麼區別?另外,爲什麼需要將ArrayList更改爲List? – archcutbank

+0

@ user372429 ArrayList只有一個類型變量,所以'ArrayList '不會被編譯。沒有必要將變量類型更改爲List,但對接口進行編程被認爲是很好的風格,而不是實現類型。閱讀[Effective Java](http://java.sun.com/docs/books/effective/),第52項:[通過接口引用對象](http://my.safaribooksonline。com/book/programming/java/9780137150021/general-programming/ch08lev1sec8) –

0

創建一個新的實例,您應該使用Comparator<T>接口不是裸Comparator

閱讀this article

0

你可以在一個類型安全的方式如下做到這一點:

Map<String, Integer> map = new LinkedHashMap<String, Integer>(); 
map.put("four", 4); 
map.put("one", 1); 
map.put("five", 5); 
map.put("three", 3); 
map.put("two", 2); 

System.out.println(map); 

List<Map.Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());   
Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() { 
    @Override 
    public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) { 
     return e1.getValue().compareTo(e2.getValue()); 
    }    
});   
map.clear();   
for(Map.Entry<String, Integer> e : entryList) { 
    map.put(e.getKey(), e.getValue()); 
} 

System.out.println(map); 

輸出:

 
{four=4, one=1, five=5, three=3, two=2} 
{one=1, two=2, three=3, four=4, five=5}