0

如果这是重复的,我深表歉意,但我找不到任何专门回答这个特定问题的答案。

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

HashMap<String, Set<String>> myMap;

包含:

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

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

除了创建实现 Set 并覆盖该compareTo方法的包装类之外,有没有办法根据集合的长度对集合进行排序?

编辑:我应该指定我不需要使用 HashMap 来维护这个集合。我可以使用 TreeMap 或其他东西,但我不确定这是否可能,因为 Set 没有实现 Comparable。

4

5 回答 5

6

除了创建实现 Set 并覆盖 compareTo 方法的包装类之外,有没有办法根据集合的长度对集合集合进行排序?

这是一种完全可行的方法。您还可以使用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();
}

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

于 2013-02-25T20:58:22.747 回答
2
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,因为您可能会发现它很有用。

于 2013-02-25T21:11:22.807 回答
0

既然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;
   }
}

T并且V是任意类型。在您的情况下,T 等于 String,V 等于 Set。

于 2013-02-25T20:40:46.217 回答
0

我会创建一个自定义对象来同时保存SetString。让类实现Comparable,实现是使用设定的大小。然后只需使用 aList填充它并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());
    }
}
于 2013-02-25T21:00:37.720 回答
0

HashMap 不可排序。它们针对通过键查找值进行了优化。

于 2013-02-25T20:36:30.957 回答