【问题标题】:Sorting based on size of ArrayList<String> in a HashMap根据 HashMap 中 ArrayList<String> 的大小进行排序
【发布时间】:2013-11-21 20:37:45
【问题描述】:

我有一个 HashMap 定义如下

Map<String, ArrayList<String>>  map = new HashMap<String, ArrayList<String>>();

然后,我将来自数据库的数据存储在此哈希图中,并在控制台上显示如下内容,其中 ---> 左侧的条目是 ID,右侧的条目是此 ID 使用的标签

165767--->[dual-boot, windows, uninstall, ati, graphics, multiple-monitors]
6873 --->[kubuntu, re-installation]
34228--->[11.10, unity, launcher, libreoffice, icons]

我想根据他们使用的标签数量对 ID 进行降序排序,即基于 ma​​p.get(key).size() 以便输出应该是 ID 165767然后是 34228,然后是 6873,依此类推。

我尝试使用 TreeMap 进行操作,但我无法根据大小而不是 key 的值以及降序来确定如何操作。

【问题讨论】:

  • Sorting hashmap by values 的可能副本。另外,您将需要一个比较器来根据列表的长度比较列表。
  • 可以先建图再排序吗?
  • 或者......如何获取已经从数据库中排序的数据,您可以简单地将其转换为 HashMap?您应该能够使用 SQL 来做到这一点。
  • @scottb,我不认为这是可取的,即使是这样,也只有在LinkedHashMap 时才有效,因为HashMap 不维持秩序。
  • @scottb,由于无法对数据库中存在的数据格式进行排序,因此无法从数据库中提取排序数据。数据库,然后使用 HashMap。

标签: java sorting arraylist hashmap


【解决方案1】:

这将创建一个排序的 id 列表。

List<String> sortedIds = new ArrayList<String>(map.getKeys());
Collections.sort(sortedIds, new Comparator<String>() {
    public int compare(String a, String b) {
        return map.get(b).size() - map.get(a).size();
    }
});

并不是说您永远不会维护SortedMap(如TreeMap),按可变值排序(如ArrayList 的长度)。由于排序顺序用于查找值,如果 "id123" 变得大于 "id456" 而 Collection 不知道它可能会导致非常大的问题。

【讨论】:

    【解决方案2】:

    编辑

    我的输出应该根据标签的数量而不是标签的大小进行排序 身份证

    Map<String, ArrayList<String>>  map = new TreeMap<String, ArrayList<String>>();
    
    
    map.put("165767",new ArrayList<String>(Arrays.asList("dual-boot", "dual-boot", "windows", "uninstall", "ati", "graphics", "multiple-monitors")));
    map.put("6873",new ArrayList<String>(Arrays.asList("kubuntu", "kubuntu", "re-installation")));
    map.put("0000000000000000",new ArrayList<String>(Arrays.asList("test","test", "test")));
    map.put("0125",new ArrayList<String>(Arrays.asList("dual-boot", "windows", "uninstall", "ati", "graphics", "multiple-monitors")));
    
    
    for(ArrayList<String> l : map.values()){
        Set<String> hs = new HashSet<>();
        hs.addAll(l);
        l.clear();
        l.addAll(hs);
    }
    
    List<ArrayList<String>> l = new ArrayList<>(map.values());
    Collections.sort(l, new Comparator<ArrayList<String>>(){
        public int compare(ArrayList<String> s1, ArrayList<String> s2){
            return Integer.compare(s2.size(), s1.size());                
        }});
    
    for(ArrayList<String> a : l){
        Iterator<Entry<String, ArrayList<String>>> iter = map.entrySet().iterator();
        while (iter.hasNext()) {
            Entry<String, ArrayList<String>> e = iter.next();
            if(e.getValue().equals(a)){
    
                System.out.println(e.getKey() + "-" + a);
                iter.remove();
            }
        }
    }
    

    输出:

    0125-[uninstall, dual-boot, graphics, windows, ati, multiple-monitors]
    165767-[uninstall, dual-boot, graphics, windows, ati, multiple-monitors]
    6873-[re-installation, kubuntu]
    0000000000000000-[test]
    

    【讨论】:

    • 我认为您误解了这个问题。我的输出应该根据标签数量而不是 ID 的大小进行排序。您的输出看起来像是根据 ID 的大小进行排序。
    • 是的,这就是我一直在寻找的。感谢您的帮助。只是多一点帮助。假设我的标签可能有重复。我怎样才能将它们从最终显示中删除?
    • @user2916886 在​​我的示例中,有一个重复的标签。不确定我是否回答了您的问题...
    • 我的意思是假设如果 ID 6873 的标签列表为 [kubuntu,re-installation,kubuntu] 那么我怎样才能在这里删除额外的“kubuntu”,即每个数组列表中的重复标签
    • @user2916886 检查我的编辑。基本上,您可以将元素添加到不允许重复的 hashSet 中,然后清除 arrayList 并将 hashset 的元素重新添加到此 arrayList 中。
    【解决方案3】:

    我有类似的情况,这段代码对我有用(有时我有空值):

         private static Map<Object,List<Object>> sortByArraySizeDesc(Map<Object,List<Object>> map) {
             List<List<Object>> list = new LinkedList(map.entrySet());
             Collections.sort(list, new Comparator() {
                  public int compare(Object o1, Object o2) { 
                      if (o1 == null && o2 == null) { return 0; }
                      else if (o1 == null) { return 1;}
                      else if (o2 == null) { return -1; }
                      int size1 = ((List) ((Map.Entry) (o1)).getValue()).size();
                      int size2 = ((List) ((Map.Entry) (o2)).getValue()).size();
                      return size2 - size1;
                  }
             });
    
            Map res = new LinkedHashMap();
            for (Iterator it = list.iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry)it.next();
                res.put(entry.getKey(), entry.getValue());
            }
            return res;
        } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-31
      • 2014-05-13
      • 2014-04-27
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2013-09-09
      • 1970-01-01
      相关资源
      最近更新 更多