2016-01-23 60 views
1

我有使用該代碼的字符串值按字母順序排序一個Java地圖:Java - 如何根據第一個字母對地圖值進行排序?

public <K, V> LinkedHashMap<K, V> sortMapByValues(Map<K, V> map) { 
    SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
     new Comparator<Map.Entry<K, V>>() { 
      @Override 
      public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) { 
       // Sort this word alphabetically in the map : 
       String a = (String)e1.getValue(); 
       String b = (String)e2.getValue(); 

       int diff = a.compareToIgnoreCase(b); 

       if (diff == 0) 
        diff = a.compareTo(b); 

       return diff != 0 ? diff : 1; // Fix words having the same spelling. 
      } 
     } 
    ); 

    sortedEntries.addAll(map.entrySet()); 

    LinkedHashMap<K, V> sortedMap = new LinkedHashMap<K, V>(); 

    for(Map.Entry<K, V> sortedEntry: sortedEntries) 
     sortedMap.put(sortedEntry.getKey(), sortedEntry.getValue()); 

    return sortedMap; 
} 

由於地圖有成千上萬的值,上面的代碼工作速度不夠快讓我迅速想要的結果。現在我需要更改此代碼並更新它以根據另一個條件對Map值進行排序,而不是按字母順序排序。

我有字母變體的ArrayList,如:

ArrayList lettersArrayList = new ArrayList<String>(Arrays.asList("E", "C", "A", "Z", "Q", "R", "B", "L", "D", ...)); 

此ArrayList中值由用戶指定所以他們可能有其他字母的數值和順序號。 我需要根據此ArrayList對Map的字符串值進行排序,因此以「E」開頭的單詞先出現,然後出現以「C」開頭的單詞,依此類推。這可能嗎?

回答

1

首先,你的比較是不正確的:

return diff != 0 ? diff : 1; 

如果ab拼寫相同,比較ab給1,這意味着a > b,並比較ba也給出1,這意味着b > a。您可以使用

return diff != 0 ? diff : Integer.compare(System.identityHashCode(e1), System.identityHashCode(e2)); 

(幾乎)是正確的。如果你使用了大量的內存,並且兩個單獨的對象碰巧結束了相同的系統哈希碼,這仍然可以使兩個條目相同,當它們實際上不同時,這是非常非常不可能的。

現在,爲了回答你的問題,你需要的是比較你的兩個條目的第一個字母的指數:

String a = (String)e1.getValue(); 
String b = (String)e2.getValue(); 

int index1 = list.indexOf(a.substring(0, 1)); 
int index2 = list.indexOf(b.substring(0, 1)); 

int diff = Integer.compare(index1, index2); 

這將工作,但將是非常低效的,因爲

  • indexOf()是O(n)
  • 您最好使用Character而不是String來存儲單個字符。

因此,而不是一個List<String>存儲的字母,你應該使用HashMap<Character, Integer>,其中每個字母將與它的位置有關。在這個映射中查找將是O(1),使得比較器更快。

+0

非常感謝您的詳細解答和糾正我的代碼。至於使用字符而不是字符串,我已經這樣做了,但我爲了一些測試目的而改變了我的代碼。我將使用Character編碼它以提供更快的性能。 – Brad

相關問題