2012-01-13 111 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); 
    } 
} 
相关问题