2012-01-13 30 views
2

我想一兩個HashMap方式進行排序。默認方式:按字母順序排列,第二種方法:按鍵數字排列,高位排在最前面。我已經四處搜尋,但找不到關於這個主題的任何內容,而且我發現的內容不起作用。如果無法對它們進行排序(我希望頂部按鍵最高的人,隨着人們有更低的按鍵而減少,然後按字母順序排序其餘所有人(以0作爲其鍵)。以下是我試過到目前爲止:排序一個HashMap,同時保持重複

private HashMap<String, Integer> userGains = new HashMap<String, Integer>(); 

public void sortGains(int skill, int user) { 
    userGains.put(users.get(user).getUsername(), users.get(user).getGainedExperience(skill)); 
    HashMap<String, Integer> map = sortHashMap(userGains); 
    for (int i = 0; i < map.size(); i++) { 
     Application.getTrackerOutput().getOutputArea(skill).append(users.get(user).getUsername() + " gained " + map.get(users.get(user).getUsername()) + " experience in " + getSkillName(skill) + ".\n"); 
    } 
} 

public LinkedHashMap<String, Integer> sortHashMap(HashMap<String, Integer> passedMap) { 
    List<String> mapKeys = new ArrayList<String>(passedMap.keySet()); 
    List<Integer> mapValues = new ArrayList<Integer>(passedMap.values()); 
    LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<String, Integer>(); 

    Collections.sort(mapValues); 
    Collections.sort(mapKeys); 

    Iterator<Integer> it$ = mapValues.iterator(); 
    while (it$.hasNext()) { 
     Object val = it$.next(); 
     Iterator<String> keyIt = mapKeys.iterator(); 
     while (keyIt.hasNext()) { 
      Object key = keyIt.next(); 
      String comp1 = passedMap.get(key).toString(); 
      String comp2 = val.toString(); 
      if (comp1.equals(comp2)) { 
       passedMap.remove(key); 
       mapKeys.remove(key); 
       sortedMap.put((String) key, (Integer) val); 
       break; 
      } 
     } 
    } 
    return sortedMap; 
} 

既然你不能運行,這裏是一個SSCCE:

private HashMap<String, Integer> userGains = new HashMap<String, Integer>(); 

private Object[][] testUsers = { { "Test user", 15 }, { "Test", 25 }, { "Hello", 11 }, { "I'm a user", 21 }, { "No you're not!", 14 }, { "Yes I am!", 45 }, { "Oh, okay. Sorry about the confusion.", 0 }, { "It's quite alright.", 0 } }; 

public static void main(String[] arguments) { 
    new Sorting().sortGains(); 
} 

public void sortGains() { 
    for (Object[] test : testUsers) { 
     userGains.put((String) test[0], (Integer) test[1]); 
    } 
    HashMap<String, Integer> map = sortHashMap(userGains); 
    for (int i = 0; i < map.size(); i++) { 
     System.out.println(testUsers[i][0] + " gained " + map.get(testUsers[i][0]) + " experience."); 
    } 
} 

public LinkedHashMap<String, Integer> sortHashMap(HashMap<String, Integer> passedMap) { 
    List<String> mapKeys = new ArrayList<String>(passedMap.keySet()); 
    List<Integer> mapValues = new ArrayList<Integer>(passedMap.values()); 
    LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<String, Integer>(); 

    Collections.sort(mapValues); 
    Collections.sort(mapKeys); 

    Iterator<Integer> it$ = mapValues.iterator(); 
    while (it$.hasNext()) { 
     Object val = it$.next(); 
     Iterator<String> keyIt = mapKeys.iterator(); 
     while (keyIt.hasNext()) { 
      Object key = keyIt.next(); 
      String comp1 = passedMap.get(key).toString(); 
      String comp2 = val.toString(); 
      if (comp1.equals(comp2)) { 
       passedMap.remove(key); 
       mapKeys.remove(key); 
       sortedMap.put((String) key, (Integer) val); 
       break; 
      } 
     } 
    } 
    return sortedMap; 
} 

程序的輸出是目前:

Test user gained 15 experience. 
Test gained 25 experience. 
Hello gained 11 experience. 
I'm a user gained 21 experience. 
No you're not! gained 14 experience. 
Yes I am! gained 45 experience. 
Oh, okay. Sorry about the confusion. gained 0 experience. 
It's quite alright. gained 0 experience. 

當我需要它是:

Yes I am! gained 45 experience. // start numeric sorting here, by highest key. 
Test gained 25 experience. 
I'm a user gained 21 experience. 
Test user gained 15 experience. 
No you're not! gained 14 experience. 
Hello gained 11 experience. 
It's quite alright. gained 0 experience. // start alphabetical sorting here, if possible. 
Oh, okay. Sorry about the confusion. gained 0 experience. 

任何見解?

回答

1

您在顯示值犯了一個錯誤。

HashMap<String, Integer> map = sortHashMap(userGains); 
for (int i = 0; i < map.size(); i++) { 
    System.out.println(testUsers[i][0] + " gained " + map.get(testUsers[i][0]) + " experience."); 
} 

你需要顯示在地圖的值,而不是原始數組的值。

這應該這樣做:

HashMap<String, Integer> map = sortHashMap(userGains); 
for (Entry<String, Integer> entry : map.entrySet()) { 
    System.out.println(entry.getKey() + " gained " + entry.getValue() + " experience."); 
} 

你只需要顛倒順序。另外我建議宣佈同Map而不是HashMapLinkedHashMap通過自己和他人,以避免混亂。你的分類也可以簡單地用Comparable完成。這裏有一個改進:

private Map<String, Integer> userGains = new HashMap<String, Integer>(); 

private Object[][] testUsers = { { "Test user", 15 }, { "Test", 25 }, { "Hello", 11 }, { "I'm a user", 21 }, { "No you're not!", 14 }, { "Yes I am!", 45 }, { "Oh, okay. Sorry about the confusion.", 0 }, { "It's quite alright.", 0 } }; 

public static void main(String[] arguments) { 
    new Sorting().sortGains(); 
} 

public void sortGains() { 
    for (Object[] test : testUsers) { 
     userGains.put((String) test[0], (Integer) test[1]); 
    } 

    Map<String, Integer> map = createSortedMap(userGains); 

    for (Entry<String, Integer> entry : map.entrySet()) { 
     System.out.println(entry.getKey() + " gained " + entry.getValue() + " experience."); 
    } 
} 

public Map<String, Integer> createSortedMap(Map<String, Integer> passedMap) { 
    List<Entry<String, Integer>> entryList = new ArrayList<Entry<String, Integer>>(passedMap.entrySet()); 

    Collections.sort(entryList, new Comparator<Entry<String, Integer>>() { 

     @Override 
     public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) { 
      if (!e1.getValue().equals(e2.getValue())) { 
       return e1.getValue().compareTo(e2.getValue()) * -1; // The * -1 reverses the order. 
      } else { 
       return e1.getKey().compareTo(e2.getKey()); 
      } 
     } 
    }); 

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

    for (Entry<String, Integer> entry : entryList) { 
     orderedMap.put(entry.getKey(), entry.getValue()); 
    } 

    return orderedMap; 
} 
+0

太棒了!儘管如此,你知道我該如何反轉該方法的輸出?編輯:更改'Collections.sort(mapValues);'到'Collections.sort(mapValues,Collections.reverseOrder());'工作得很好:)再次感謝。 – Aeterna 2012-01-13 19:28:37

+0

我用一個例子更新了答案。 – BalusC 2012-01-13 19:30:31

+0

謝謝,這比我使用的更容易理解! – Aeterna 2012-01-13 19:31:43

5

根本不可能根據對HashMap進行分類。根據定義,HashMap中的密鑰是無序的。如果你希望你的Map的鍵進行排序,然後用TreeMap用適當的Comparator對象。如果你想訪問相同數據的多個方法可以創建多個TreeMaps不同Comparator秒。

+0

有沒有辦法,我可以進行排序,然後獲得用戶體驗的方法嗎?我有一個** User **超類,它包含所有的信息,然後是一個包含所有這些信息的用戶ArrayList。 – Aeterna 2012-01-13 19:11:48

+0

當然,你一定可以對'ArrayList'進行排序;使用'Collections.sort()'並提供一個合適的'Comparator'實現。 – 2012-01-13 19:14:49

+0

啊我明白了。我在前面查看並找到了提供的方法來對「HashMap」進行排序,但我認爲這太好了,不能實現。使用'Collections.sort()'是否允許我保留重複項,還是在'Comparator'中完成? – Aeterna 2012-01-13 19:19:12

1

This問題通過對TreeMap中的值進行排序來處理您要做的事。如果你選擇最多的答案並修改比較器來排序值然後鍵,它應該給你你想要的。

實際上,創建具有指向樹形圖字段的比較(因此它可以查找值)。而TreeMap使用這個比較器。當項目被添加到樹形圖,比較器查找該值並執行上

  • 的比較,如果值一<值b,則返回1
  • 如果值一>值b,返回-1
  • 如果該鍵的鍵< b,返回1
  • 如果該鍵的鍵> b,返回-1
  • 否則,返回0

複印荷蘭國際集團大量的代碼從這個問題的答案(沒有檢查,看看是否代碼工作,因爲它只是一個想法):

public class Main { 

    public static void main(String[] args) { 

     ValueComparator<String> bvc = new ValueComparator<String>(); 
     TreeMap<String,Integer> sorted_map = new TreeMap<String,Integer>(bvc); 
     bvc.setBase(sorted_map); 

     // add items 
     // .... 

     System.out.println("results"); 
      for (String key : sorted_map.keySet()) { 
      System.out.println("key/value: " + key + "/"+sorted_map.get(key)); 
     } 
    } 

} 

class ValueComparator implements Comparator<String> { 
    Map base; 

    public setBase(Map<String,Integer> base) { 
     this.base = base; 
    } 

    public int compare(String a, String b) { 
     Integer value_a = base.get(a); 
     Integer value_b = base.get(b); 

     if(value_a < value_b) { 
      return 1; 
     } 
     if(value_a>< value_b) { 
      return -1; 
     } 
     return a.compareTo(b); 
    } 
} 
相關問題