【问题标题】:How to sort a HashMap in Java [duplicate]如何在Java中对HashMap进行排序[重复]
【发布时间】:2010-10-21 07:12:47
【问题描述】:

我们如何对HashMap<key, ArrayList> 进行排序?

我想根据ArrayList 中的值进行排序。

【问题讨论】:

    标签: java sorting hashmap


    【解决方案1】:

    你必须使用 HashMap 吗?如果您只需要地图接口,请使用TreeMap


    如果要通过比较 HashMap 中的值进行排序。您必须编写代码来执行此操作,如果您想在对 HashMap 的值进行排序后执行此操作:

    Map<String, Person> people = new HashMap<>();
    Person jim = new Person("Jim", 25);
    Person scott = new Person("Scott", 28);
    Person anna = new Person("Anna", 23);
    
    people.put(jim.getName(), jim);
    people.put(scott.getName(), scott);
    people.put(anna.getName(), anna);
    
    // not yet sorted
    List<Person> peopleByAge = new ArrayList<>(people.values());
    
    Collections.sort(peopleByAge, Comparator.comparing(Person::getAge));
    
    for (Person p : peopleByAge) {
        System.out.println(p.getName() + "\t" + p.getAge());
    }
    

    如果您想经常访问此排序列表,则可以将元素插入HashMap&lt;TreeSet&lt;Person&gt;&gt;,尽管集合和列表的语义有些不同。

    【讨论】:

    • 还有几点:首先,您需要做出两个决定:(1)您是要按值排序还是按键排序,(2)您是否可以控制在开始时收集,因此您可以使用内置排序,而不是当您收到现有地图并且只想以某种顺序遍历它们时。此外,LinkedHashMap 可以通过插入顺序(我经常喜欢调试)或访问顺序来维护。最后,如果你做了很多这样的事情,你可以看看 Java 1.6 和 NavigableMap,很棒的东西!
    • 如果您想按键排序,请改用 SortedMap。它为您提供自动排序的键。
    • TreeMap 是我来到这里时一直在寻找的答案,谢谢。
    • TreeMap 似乎是一个非常糟糕的类名称选择......应该改为SortedMap。从名称来看,我认为它根本不是Map,而是某种Tree...TreeTreeMap 部分实际上更像是一个不应该关注用户的实现细节类。
    • @ArtOfWarfare: 正是Tree 一个实现细节,因此在用户选择使用哪个类来实现SortedMap 接口时应该关注...
    【解决方案2】:

    按hasmap键排序的列表:

    SortedSet<String> keys = new TreeSet<String>(myHashMap.keySet());
    

    按哈希映射值排序的列表:

    SortedSet<String> values = new TreeSet<String>(myHashMap.values());
    

    如果地图值重复:

    List<String> mapValues = new ArrayList<String>(myHashMap.values());
    Collections.sort(mapValues);
    

    祝你好运!

    【讨论】:

    • 能分享一下原因吗? @安德鲁
    • HashMap 不是 Map 接口的实现,以保持其键或值的顺序。如果它是 LinkedHashMap 你可能是对的。在这种情况下,您只能拥有已排序的键或已排序的哈希映射值。我认为您的知识和方法有点错误。请考虑此评论并重新评估您的投票。谢谢@Andrew
    【解决方案3】:

    http://snipplr.com/view/2789/sorting-map-keys-by-comparing-its-values/

    拿到钥匙

    List keys = new ArrayList(yourMap.keySet());
    

    排序

     Collections.sort(keys)
    

    打印出来。

    在任何情况下,您都不能在 HashMap 中对值进行排序(根据 API This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time ]。

    尽管您可以将所有这些值推送到LinkedHashMap,以供以后使用。

    【讨论】:

      【解决方案4】:

      看来您可能需要树状图。

      http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html

      如果适用,您可以将自定义比较器传递给它。

      【讨论】:

        【解决方案5】:

        在 Java 8 中:

        Comparator<Entry<String, Item>> valueComparator = 
            (e1, e2) -> e1.getValue().getField().compareTo(e2.getValue().getField());
        
        Map<String, Item> sortedMap = 
            unsortedMap.entrySet().stream().
            sorted(valueComparator).
            collect(Collectors.toMap(Entry::getKey, Entry::getValue,
                                     (e1, e2) -> e1, LinkedHashMap::new));
        

        使用Guava

        Map<String, Item> map = ...;
        Function<Item, Integer> getField = new Function<Item, Integer>() {
            public Integer apply(Item item) {
                return item.getField(); // the field to sort on
            }
        };
        comparatorFunction = Functions.compose(getField, Functions.forMap(map));
        comparator = Ordering.natural().onResultOf(comparatorFunction);
        Map<String, Item> sortedMap = ImmutableSortedMap.copyOf(map, comparator);
        

        【讨论】:

        • 为什么我们必须添加一个新库来执行本机可用的功能?
        • Java 8 比较器可以改写为:Comparator&lt;Map.Entry&lt;String, String&gt;&gt; valueComparator = Comparator.comparing(Map.Entry::getValue().getField());
        【解决方案6】:

        自定义比较功能,其中包括土耳其语字母表除英语以外的其他不同语言的功能。

        public <K extends Comparable,V extends Comparable> LinkedHashMap<K,V> sortByKeys(LinkedHashMap<K,V> map){
            List<K> keys = new LinkedList<K>(map.keySet());
            Collections.sort(keys, (Comparator<? super K>) new Comparator<String>() {
                @Override
                public int compare(String first, String second) {
                    Collator collator = Collator.getInstance(Locale.getDefault());
                    //Collator collator = Collator.getInstance(new Locale("tr", "TR"));
                    return collator.compare(first, second);
                }
            });
        
            LinkedHashMap<K,V> sortedMap = new LinkedHashMap<K,V>();
            for(K key: keys){
                sortedMap.put(key, map.get(key));
            }
        
            return sortedMap;
        }
        

        下面是使用示例

        LinkedHashMap<String, Boolean> ligList = new LinkedHashMap<String, Boolean>();
        ligList = sortByKeys(ligList);
        

        【讨论】:

          【解决方案7】:

          没有更多信息,很难确切知道您想要什么。但是,在选择要使用的数据结构时,您需要考虑到您需要它的用途。哈希图不是为排序而设计的——它们是为方便检索而设计的。因此,在您的情况下,您可能必须从哈希图中提取每个元素,并将它们放入更利于排序的数据结构中,例如堆或集合,然后在那里对它们进行排序。

          【讨论】:

          • 其实它不是用来排序的,hash map是用来存储从文件中读取的数据及其值
          • 我们只需要根据hash map hashmap map中数组列表的一个元素进行排序
          • 是的,听起来你想要的就是其他人所说的 - TreeMap。 TreeMaps 看起来很像 HashMaps,除了你也可以对它们进行排序。万岁!
          • 如果我们在哈希映射中存储(key,person)person 是一个类,它有四个对象如果我们想要基于其中一个对象进行排序,我们将如何做到这一点...?跨度>
          【解决方案8】:

          如果您想将 Map 与 SortedMap 结合起来进行高效检索,您可以使用ConcurrentSkipListMap

          当然,您需要将键作为用于排序的值。

          【讨论】:

            【解决方案9】:

            您是否考虑过使用 LinkedHashMap()..?

              public static void main(String[] args) {
                Map<Object, Object> handler = new LinkedHashMap<Object, Object>();
                handler.put("item", "Value");
                handler.put(2, "Movies");
                handler.put("isAlive", true);
            
                for (Map.Entry<Object, Object> entrY : handler.entrySet())
                    System.out.println(entrY.getKey() + ">>" + entrY.getValue());
            
                List<Map.Entry<String, Integer>> entries = new ArrayList<Map.Entry<String, Integer>>();
                Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
                    public int compare(Map.Entry<String, Integer> a,
                            Map.Entry<String, Integer> b) {
                        return a.getValue().compareTo(b.getValue());
                    }
                });
            }
            

            产生一个有组织的链接对象。

             item>>Value
             2>>Movies
             isAlive>>true
            

            检查从here..挑选的排序部分。

            【讨论】:

              【解决方案10】:

              我开发了一个类,可用于根据键和值对地图进行排序。基本思想是,如果您使用键对地图进行排序,然后从您的地图创建一个 TreepMap,它将按键对地图进行排序。如果按值排序,则从 entrySet 创建一个列表,并使用比较器接口对列表进行排序。

              这里是完整的解决方案:

              public static void main(String[] args) {
                  Map<String, Integer> unSortedMap = new LinkedHashMap<String, Integer>();
                  unSortedMap.put("A", 2);
                  unSortedMap.put("V", 1);
                  unSortedMap.put("G", 5);
                  System.out.println("Unsorted Map :\n");
                  for (Map.Entry<String, Integer> entry : unSortedMap.entrySet()) {
                      System.out.println(entry.getKey() + "   " + entry.getValue());
                  }
                  System.out.println("\n");
                  System.out.println("Sorting Map Based on Keys :\n");
                  Map<String, Integer> keySortedMap = new TreeMap<String, Integer>(unSortedMap);
                  for (Map.Entry<String, Integer> entry : keySortedMap.entrySet()) {
                      System.out.println(entry.getKey() + "   " + entry.getValue());
                  }
                  System.out.println("\n");
                  System.out.println("Sorting Map Based on Values :\n");
                  List<Entry<String, Integer>> entryList = new ArrayList<Entry<String, Integer>>(unSortedMap.entrySet());
                  Collections.sort(entryList, new Comparator<Entry<String, Integer>>() {
              
                      @Override
                      public int compare(Entry<String, Integer> obj1, Entry<String, Integer> obj2) {
                          return obj1.getValue().compareTo(obj2.getValue());
                      }
                  });
                  unSortedMap.clear();
                  for (Entry<String, Integer> entry : entryList) {
                      unSortedMap.put(entry.getKey(), entry.getValue());
                      System.out.println(entry.getKey() + "   " + entry.getValue());
                  }
              }
              

              代码已正确测试:D

              【讨论】:

              • 这不是真正的。此外,您的排序值存储在 entryList 中,为什么要清除 unSortedMap 并再次打印?我建议创建一个名为 sortMap 的方法,它以 unSortedMap 作为参数并返回 entryList
              【解决方案11】:

              HashMap 按值排序:

              正如其他人指出的那样。 HashMaps 便于查找,如果您更改它或尝试在地图本身内部进行排序,您将不再有 O(1) 查找。

              你的排序代码如下:

              class Obj implements Comparable<Obj>{
                  String key;
                  ArrayList<Integer> val;
                  Obj(String key, ArrayList<Integer> val)
                  {
                  this.key=key;
                  this.val=val;
                  }
                  public int compareTo(Obj o)
                  {
                   /* Write your sorting logic here. 
                   this.val compared to o.val*/
                   return 0;
                  }
              }
              
              public void sortByValue(Map<String, ArrayList<>> mp){
              
                  ArrayList<Obj> arr=new ArrayList<Obj>();
                  for(String z:mp.keySet())//Make an object and store your map into the arrayList
                  {
              
                      Obj o=new Obj(z,mp.get(z));
                      arr.add(o);
                  }
                  System.out.println(arr);//Unsorted
                  Collections.sort(arr);// This sorts based on the conditions you coded in the compareTo function.
                  System.out.println(arr);//Sorted
              }
              

              【讨论】:

                【解决方案12】:

                一个正确的答案。

                HashMap<Integer, Object> map = new HashMap<Integer, Object>();
                
                ArrayList<Integer> sortedKeys = new ArrayList<Integer>(map.keySet());
                Collections.sort(sortedKeys, new Comparator<Integer>() {
                  @Override
                  public int compare(Integer a, Integer b) {
                    return a.compareTo(b);
                  }
                });
                
                for (Integer key: sortedKeys) {
                  //map.get(key);
                }
                

                请注意,正如其他答案所指出的,HashMap 本身无法维护排序。这是一个 hash 映射,散列值是未排序的。因此,您可以在需要时对键进行排序,然后按顺序访问值,如上所示,或者您可以找到一个不同的集合来存储您的数据,例如 Pairs/Tuples 的 ArrayList,例如在Apache Commons:

                https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html

                【讨论】:

                  【解决方案13】:

                  按键排序:

                  public static void main(String[] args) {
                      Map<String,String> map = new HashMap<>();
                  
                      map.put("b", "dd");
                      map.put("c", "cc");
                      map.put("a", "aa");
                  
                      map = new TreeMap<>(map);
                  
                      for (String key : map.keySet()) {
                          System.out.println(key+"="+map.get(key));
                      }
                  }
                  

                  【讨论】:

                  • 但我们没有提供任何东西来指定升序/降序和按值排序。
                  【解决方案14】:

                  我开发了一个经过全面测试的工作解决方案。希望对你有帮助

                  import java.io.BufferedReader;
                  import java.io.IOException;
                  import java.util.ArrayList;
                  import java.util.Collections;
                  import java.util.Comparator;
                  import java.util.HashMap;
                  import java.util.List;
                  import java.util.StringTokenizer;
                  
                  
                  public class Main {
                      public static void main(String[] args) {
                      try {
                          BufferedReader in = new BufferedReader(new java.io.InputStreamReader           (System.in));
                              String str;
                  
                          HashMap<Integer, Business> hm = new HashMap<Integer, Business>();
                          Main m = new Main();
                  
                  
                          while ((str = in.readLine()) != null) {
                  
                  
                              StringTokenizer st = new StringTokenizer(str);
                              int id = Integer.parseInt(st.nextToken());    // first integer
                              int rating = Integer.parseInt(st.nextToken());    // second 
                  
                              Business a = m.new Business(id, rating);
                  
                  
                              hm.put(id, a);
                  
                  
                              List<Business> ranking = new ArrayList<Business>(hm.values());
                  
                              Collections.sort(ranking, new Comparator<Business>() {
                  
                                  public int compare(Business i1, Business i2) {
                                      return i2.getRating() - i1.getRating();
                                  }
                              });
                  
                              for (int k=0;k<ranking.size();k++) {
                                  System.out.println((ranking.get(k).getId() + " " + (ranking.get(k)).getRating()));
                              }
                  
                  
                          }
                          in.close();
                  
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  
                  
                  }
                  public class Business{
                  
                      Integer id;
                      Integer rating;
                  
                      public Business(int id2, int rating2)
                      {
                          id=id2;
                          rating=rating2;
                  
                      }
                  
                      public Integer getId()
                      {
                          return id;
                      }
                      public Integer getRating()
                      {
                          return rating;
                      }
                  
                  
                  }
                  }
                  

                  【讨论】:

                    【解决方案15】:

                    HashMap 不维护任何顺序,所以如果你想要任何一种排序,你需要将它存储在其他东西中,这是一个映射并且可以有某种排序,比如 LinkedHashMap

                    下面是一个简单的程序,通过它你可以按键、值、升序、降序排序..(如果你修改了压缩器,你可以对键和值使用任何排序)

                    package com.edge.collection.map;
                    
                    import java.util.Collections;
                    import java.util.Comparator;
                    import java.util.HashMap;
                    import java.util.LinkedHashMap;
                    import java.util.LinkedList;
                    import java.util.List;
                    import java.util.Map;
                    import java.util.Map.Entry;
                    
                    public class SortMapByKeyValue {
                    Map<String, Integer> map = new HashMap<String, Integer>();
                    
                    public static void main(String[] args) {
                    
                        SortMapByKeyValue smkv = new SortMapByKeyValue();
                        smkv.createMap();
                    
                        System.out.println("After sorting by key ascending order......");
                        smkv.sortByKey(true);
                    
                        System.out.println("After sorting by key descindeng order......");
                        smkv.sortByKey(false);
                    
                        System.out.println("After sorting by value ascending order......");
                        smkv.sortByValue(true);
                    
                        System.out.println("After sorting by value  descindeng order......");
                        smkv.sortByValue(false);
                    
                    }
                    
                    void createMap() {
                        map.put("B", 55);
                        map.put("A", 80);
                        map.put("D", 20);
                        map.put("C", 70);
                        map.put("AC", 70);
                        map.put("BC", 70);
                        System.out.println("Before sorting......");
                        printMap(map);
                    }
                    
                    void sortByValue(boolean order) {
                    
                        List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(map.entrySet());
                        Collections.sort(list, new Comparator<Entry<String, Integer>>() {
                            public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
                                if (order) {
                                    return o1.getValue().compareTo(o2.getValue());
                                } else {
                                    return o2.getValue().compareTo(o1.getValue());
                    
                                }
                            }
                        });
                        Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
                        for (Entry<String, Integer> entry : list) {
                            sortedMap.put(entry.getKey(), entry.getValue());
                        }
                        printMap(sortedMap);
                    
                    }
                    
                    void sortByKey(boolean order) {
                    
                        List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(map.entrySet());
                        Collections.sort(list, new Comparator<Entry<String, Integer>>() {
                            public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
                                if (order) {
                                    return o1.getKey().compareTo(o2.getKey());
                                } else {
                                    return o2.getKey().compareTo(o1.getKey());
                    
                                }
                            }
                        });
                        Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
                        for (Entry<String, Integer> entry : list) {
                            sortedMap.put(entry.getKey(), entry.getValue());
                        }
                        printMap(sortedMap);
                    }
                    
                    public void printMap(Map<String, Integer> map) {
                        // System.out.println(map);
                        for (Entry<String, Integer> entry : map.entrySet()) {
                            System.out.println(entry.getKey() + " : " + entry.getValue());
                        }
                    }
                    }
                    

                    这里是 git link

                    【讨论】:

                      【解决方案16】:

                      将 hashmap 转换为具有 pair 类的 ArrayList

                      Hashmap<Object,Object> items = new HashMap<>();
                      

                      List<Pair<Object,Object>> items = new ArrayList<>();
                      

                      所以你可以随意排序,或者通过添加顺序来排序。

                      【讨论】:

                        【解决方案17】:

                        在 Java 中按值对 HashMap 进行排序:

                        public class HashMapSortByValue {
                            public static void main(String[] args) {
                        
                                HashMap<Long,String> unsortMap = new HashMap<Long,String>();
                                    unsortMap.put(5l,"B");
                                    unsortMap.put(8l,"A");
                                    unsortMap.put(2l, "D");
                                    unsortMap.put(7l,"C" );
                        
                                    System.out.println("Before sorting......");
                                    System.out.println(unsortMap);
                        
                                    HashMap<Long,String> sortedMapAsc = sortByComparator(unsortMap);
                                    System.out.println("After sorting......");
                                    System.out.println(sortedMapAsc);
                        
                            }
                        
                            public static HashMap<Long,String> sortByComparator(
                                    HashMap<Long,String> unsortMap) {
                        
                                    List<Map.Entry<Long,String>> list = new LinkedList<Map.Entry<Long,String>>(
                                        unsortMap.entrySet());
                        
                                    Collections.sort(list, new Comparator<Map.Entry<Long,String>> () {
                                        public int compare(Map.Entry<Long,String> o1, Map.Entry<Long,String> o2) {
                                            return o1.getValue().compareTo(o2.getValue());
                                        }
                                    });
                        
                                    HashMap<Long,String> sortedMap = new LinkedHashMap<Long,String>();
                                    for (Entry<Long,String> entry : list) {
                                      sortedMap.put(entry.getKey(), entry.getValue());
                                    }
                                    return sortedMap;
                                  }
                        
                        }
                        

                        【讨论】:

                          猜你喜欢
                          • 2023-04-06
                          • 1970-01-01
                          • 2015-02-13
                          • 1970-01-01
                          • 2011-12-28
                          • 2016-10-14
                          • 2013-08-28
                          • 1970-01-01
                          相关资源
                          最近更新 更多