【问题标题】:Order HashMap alphabetically by value [duplicate]按值的字母顺序对HashMap进行排序[重复]
【发布时间】:2011-05-08 04:52:01
【问题描述】:

我有一个HashMap<Object, Student>,其中 Object 是 Student 的 ID,Student 是来自 Student 的对象。

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

【问题讨论】:

  • 这取决于家庭作业“想要”你做什么。由于没有“排序”,也许它希望您以特定顺序显示/导出学生(在 HashMap 中)......无论如何,家庭作业就是这样变化无常的。
  • 这必须是 Java 的 10 大问题之一。
  • HashMap 不提供对自身进行排序的方法。因此,唯一的选择是获得所需的视图并对视图进行排序。但请注意,从视图中删除也会从 HashMap 本身中删除

标签: java sorting collections


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    HashMaps 不能按它们的值排序。 Map 是为基于键的恒定时间查找而设计的,因此不需要按值排序。如果您需要按名称排序,我建议使用SortedSet 并创建一个按名称排序的比较器。

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

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

    【讨论】:

    • 是的,我假设学生总是有名字
    • 而且学生本身不为空。
    【解决方案3】:

    地图不能按值排序。不过,您可以这样做:

    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());
        }
    });
    

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

    祝你好运。

    【讨论】:

    • TreeMaps 是有序的。说一般地图不可能是不完全准确的。是的,我知道 OP 说要使用 HashMap,但你说的是 Map,而不是 HashMap。
    • 按键排序。我说的是按值排序,而不是键。
    【解决方案4】:

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

    然后你可以将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。

    【讨论】:

      【解决方案5】:

      您可能无法对 HashMap 进行排序,但您当然可以做一些提供相同效果的操作。通过使用Javarevisited 博客上发布的优秀代码,我能够通过对 Integer 的值进行降序来对我的 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

      【讨论】:

        猜你喜欢
        • 2017-02-19
        • 2021-04-23
        • 2016-01-23
        • 1970-01-01
        • 2018-01-27
        • 2015-04-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多