如果这是重复,我道歉,但我找不到任何具体回答这一特定问题的答案。
我有一个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。
答案 0 :(得分: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();
}
此列表不是密钥的实时视图,但如果这是可接受的限制,那么这将是您最好的选择。
答案 1 :(得分: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,因为您可能会发现它很有用。
答案 2 :(得分:0)
HashMaps不可排序。它们经过优化,可以通过按键查看值。
答案 3 :(得分: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。
答案 4 :(得分:0)
我会创建一个自定义对象来同时保存Set
和String
。让类实现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());
}
}