按值按字母顺序排序HashMap

时间:2010-11-10 23:41:41

标签: java sorting collections

我有HashMap<Object, Student>,其中Object是学生的ID,而Student是Student的对象。

如何通过学生姓名student->getName()求助HashMap?

5 个答案:

答案 0 :(得分:15)

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

相反,您可以使用SortedMap实施,例如TreeMap 但是,即使是有序的地图也只能按其键排序。

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

答案 1 :(得分:4)

您可能无法对HashMap进行排序,但您当然可以做一些提供相同效果的事情。我能够对HashMap&lt; String,Integer&gt;进行排序。通过使用Javarevisited博客上发布的优秀代码降低Integer的值。相同的原则适用于HashMap&lt; String,String&gt;对象:

/*
 * 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

答案 2 :(得分: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());
    }
});

当然,假设您需要迭代值。 (为什么还要这样订购?)

祝你好运。

答案 3 :(得分:0)

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

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

如果您需要一个恒定时间查找和一个按值排序的设置,那么您可能需要维护一个地图和一个集合。

答案 4 :(得分:0)

我肯定会使用一个New Class来存储密钥和Object。

然后你可以把这个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。