2016-01-23 43 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

相关问题