2010-11-10 85 views
5

我有一个HashMap<Object, Student>其中Object是Student的ID,Student是Student的一个对象。按值按字母顺序排列哈希映射

我怎样才能通过学生的名字,student->getName()度假哈希图?

+0

这取决于什么功课“想要“你去做。由于没有“诉诸手段”,也许它要求你以特定的顺序显示/导出学生(在HashMap中)......无论如何,作业是反复无常的。 – 2010-11-10 23:54:38

+1

Dupe of http://stackoverflow.com/questions/1894081/what-is-the-easiest-way-to-sort-maps-according-to-values-in-java,http://stackoverflow.com/questions/2839003 /在java中排序哈希映射,可能还有更多。 – BalusC 2010-11-11 00:00:43

+2

这必须是前10个Java问题之一。 – 2010-11-11 01:29:46

回答

13

HashMap本质上是无序的,无法排序。

取而代之,您可以使用SortedMap实现,例如TreeMap
但是,即使是有排序的地图也只能按键进行排序。

如果您想按值排序,您需要将它们复制到排序列表中。

0

HashMaps无法按其值排序。 Map是基于密钥进行恒定时间查找的,因此按值排序不是必需的。如果您需要按名称排序,我建议使用SortedSet并创建一个按名称排序的比较器。

class StudentComparator implements Comparator<Student> { 
    int compare(Student s1, Student s2) { 
     return s1.getName().compareTo(s2.getName()); 
    } 
} 

如果你需要一个恒定时间查找和一个按值排序的集合,那么你可能需要维护一个映射和一个集合。

+0

除非它们为'null'。 – SLaks 2010-11-10 23:52:05

+0

是的,我假设一个学生总是有一个名字 – 2010-11-10 23:53:00

+1

而且学生本身不是零。 – SLaks 2010-11-11 00:04:32

1

地图不能按值排序。你可以这样做,虽然:

Collection<Student> students = map.values(); 

Collection.sort(new ArrayList<Student>(students)), new Comparator<Student>() { 
    public int compare(Student s1, Student s2) { 
     return s1.getName().compareTo(s2.getName()); 
    } 
}); 

假设,当然,你需要遍历的值。 (你为什么要这样订购?)

祝你好运。

+0

订购TreeMaps。说一般的地图不可能不完全准确。是的,我知道OP说使用HashMap,但你说的是Map,而不是HashMap。 – 2010-11-11 00:23:44

+1

按键排序。我说按价值排序,而不是按键。 – Todd 2010-11-11 00:27:35

0

我肯定会使用一个新的类来存储键和对象。

然后你可以把这个Map的每个元素都以这个类的形式放入一个ArrayList中,最后使用一个比较器对ArrayList进行排序,之后你只需构建一个新的Map。代码将是这样的:

Map<Object, Student> valueMap = new LinkedHashMap<String, String>(); 
List<Student> pairValueList = new ArrayList<PairValue>(); 

PairValue p; 
for (Map.Entry<Object, Student> entry : map.entrySet()) { 
    Object key = entry.getKey(); 
    Student value = entry.getValue();   
    p = new PairValue(key, value); 
    pairValueList.add(p); 
} 

Collections.sort(pairValueList, new Comparator<PairValue>() { 
    @Override 
    public int compare(PairValue c1, PairValue c2) { 
    return c1.getLabel().compareTo(c2.getLabel()); 
    } 
}); 

for (PairValue pv : pairValueList) { 
    valueMap.put(pv.getValue(), pv.getStudent()); 
} 

的PairValue类

class PairValue {  

    private Object value;  
    private Student student; 

    public PairValue(Object value, String student) { 
    this.value = value; 
    this.student= student; 
    } 

    public String getValue() { 
    return value; 
    } 

    public String getStudent() { 
    return student; 
    }  
} 

,这是我解决了一些类似的问题,我在过去的方式。请注意,返回的地图实现需要是一个LinkedHashMap。

4

您可能无法对HashMap进行排序,但您当然可以做一些提供相同效果的东西。通过使用发布在Javarevisited博客上的优秀代码,我能够通过递减整数值来对我的HashMap <字符串,整数>进行排序。同样的原则也适用于一个HashMap <字符串,字符串>对象:

/* 
* Java method to sort Map in Java by value e.g. HashMap or Hashtable 
* throw NullPointerException if Map contains null values 
* It also sort values even if they are duplicates 
*/ 
public static <K extends Comparable,V extends Comparable> Map<K,V> sortByValues(Map<K,V> map){ 
    List<Map.Entry<K,V>> entries = new LinkedList<Map.Entry<K,V>>(map.entrySet()); 

    Collections.sort(entries, new Comparator<Map.Entry<K,V>>() { 

     @Override 
     public int compare(Entry<K, V> o1, Entry<K, V> o2) { 
      return o1.getValue().compareTo(o2.getValue()); 
      // to compare alphabetically case insensitive return this instead 
      // o1.getValue().toString().compareToIgnoreCase(o2.getValue().toString()); 
     } 
    }); 

    //LinkedHashMap will keep the keys in the order they are inserted 
    //which is currently sorted on natural ordering 
    Map<K,V> sortedMap = new LinkedHashMap<K,V>(); 

    for(Map.Entry<K,V> entry: entries){ 
     sortedMap.put(entry.getKey(), entry.getValue()); 
    } 

    return sortedMap; 
} 

要调用这个方法,我用:

Map<String, Integer> sorted = sortByValues(myOriginalHashMapObject); 

了解更多:http://javarevisited.blogspot.com/2012/12/how-to-sort-hashmap-java-by-key-and-value.html#ixzz2akXStsGj