有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java对哈希集集合进行排序

如果这是重复的,我很抱歉,但我找不到任何具体回答这个问题的答案

我有一个HashMap,它包含一个字符串键和一个设置值。我想根据集合的长度对地图中的值进行排序。考虑:

HashMap<String, Set<String>> myMap;

包含:

{"A", {"Dukmerriot", "King", "Pumpkin"}}  
{"B", {"Steve"}}
{"C", {"Jib", "Jab", "John", "Julie"}}
{"D", {"Apple", "Amy", "Unicorn", "Charlie", "Raptor"}}
{"E", {}}

我希望能够从myMap高效地获取列表{"D", "C", "A", "B", E"}(它指定集合从最大到最小的顺序)

除了创建一个实现Set并重写compareTo方法的包装器类之外,还有其他方法可以根据集合的长度对集合进行排序吗

编辑:我应该指定不需要使用HashMap来维护此集合。我可以使用树形图或其他东西,但我不确定这是否可行,因为Set并没有实现可比性


共 (5) 个答案

  1. # 1 楼答案

    final Map<String, Set<String>> map = new HashMap<>();
    
    map.put("A", ImmutableSet.of("Dukmerriot", "King", "Pumpkin"));
    map.put("B", ImmutableSet.of("Steve"));
    map.put("C", ImmutableSet.of("Jib", "Jab", "John", "Julie"));
    map.put("D", ImmutableSet.of("Apple", "Amy", "Unicorn", "Charlie", "Raptor"));
    map.put("E", new HashSet<String>());
    
    List<String> keys = new ArrayList<>(map.keySet());
    Collections.sort(keys, new Comparator<String>() {
    
        @Override
        public int compare(String o1, String o2) {
            return Integer.valueOf(map.get(o2).size()).compareTo(map.get(o1).size());
        }
    });
    
    for (String key : keys) {
        System.out.println(key);
    }
    

    印刷品

    D
    C
    A
    B
    E
    

    我使用Google Guava的ImmutableSet,只是为了使代码简短。您可能希望查看它们的Multimap,因为您可能会发现它很有用

  2. # 2 楼答案

    哈希映射是不可排序的。它们针对按键查找值进行了优化

  3. # 3 楼答案

    因为HashMaps不维护内部秩序,所以不能这样做。你能做的最好的事情就是用map.values()获取所有的值,迭代它,看看哪个值最长

    HashMap<T, V> map = ...
    Collection<V> values = map.values();
    
    int maxLen = Integer.MIN_VALUE;
    Set<String> winner = null;
    for(V v : values) {
       if(v.size() > maxLen) {
         winner = v;
       }
    }
    

    TV是任意类型。在你的例子中,T等于String,V等于Set

  4. # 4 楼答案

    Is there a way to sort a collection of sets based on their length other than creating a wrapper class that implements Set and overriding the compareTo method?

    这是一个完全可行的方法。您还可以使用Comparator

    List<Set<String>> mySets = new ArrayList<>(myMap.values());
    mySets.sort(new Comparator<Set<String>>() {
        @Override
        public int compare(Set<String> a, Set<String> b) {
            return Integer.compare(a.size(), b.size());
        }
    });
    

    。。。但是现在您丢失了每个集合的对应键。让我们对地图条目进行排序吧

    List<Entry<String, Set<String>>> entries = new ArrayList<>(myMap.entrySet());
    entries.sort(new Comparator<Entry<String, Set<String>>>() {
        @Override
        public int compare(Entry<String, Set<String>> a,Entry<String, Set<String>> b) {
            return Integer.compare(a.getValue().size(), b.getValue().size());
        }
    });
    

    您现在可以“轻松”获得钥匙:

    List<String> sortedKeys = new ArrayList<>();
    for (Entry<String, Set<String>> e : entries) {
        sortedKeys = e.getKey();
    }
    

    此列表不会是密钥的实时视图,但如果这是一个可接受的限制,它将是您的最佳选择

  5. # 5 楼答案

    我将创建一个自定义对象来保存SetString。让类实现Comparable,实现使用设置的大小。然后只需使用List填充它,然后Collections.sort()获得所需的结果

    class A implements Comparable {
        Set set;
        String string;
    
        ...constructor etc....
    
        @Override
        public int compare(A a,A b) {
            return Integer.compare(a.set.size(), b.set.size());
        }
    }