我需要找到topN键。
我有一个输入作为HashMap的形式为(key:value):
Banana : 13
Apple: 12
Mango : 32
Orange : 12
Grape : 18
Pear : 12
Peach : 18
我创建了一个基于值排序的链接HapMap:
private static <K extends Comparable, V extends Comparable> Map<K, V> sortByValues(Map<K, V> map) {
List<Map.Entry<K, V>> entries = new LinkedList<Map.Entry<K, V>>(map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<K, V>>() {
@Override
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
Map<K, V> sortedMap = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : entries) {
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
这给了我的输出:
Mango : 32
Grape : 18
Peach : 18
Banana : 13
Apple: 12
Orange : 12
Pear : 12
现在,如果我想要进入前4名的成果,如果我想要输出,我应该如何处理:
Mango :32
Grape, Peach : 18
Banana :13
Apple, Orange, Pear: 12
我尝试遍历已排序的hashMap,并通过执行
比较后续元素的值int sizeOfMap = myValueSortedMap.size();
ArrayList<String> keyArr = new ArrayList<String>();
int cnt=0,keyVal=0;
while(cnt<(sizeOfMap-1)){
if(myValueSortedMap.values().toArray()[cnt] == myValueSortedMap.values().toArray()[cnt+1]){
keyArr.add((String) myValueSortedMap.keySet().toArray()[cnt]+ " , " +(String) myValueSortedMap.keySet().toArray()[cnt+1]);
}
else{
keyArr.add((String) myValueSortedMap.keySet().toArray()[cnt]);
keyVal = (int) myValueSortedMap.values().toArray()[cnt];
}
cnt++;
}
但这并不总是有效。
我无法想办法解决这个问题。有人可以请我带头吗?
答案 0 :(得分:7)
您可以使用两步流处理 - 第一步按数字值对条目进行分组,第二步对流内容进行排序,应用限制为4并打印结果。
map.entrySet()
.stream()
.collect(Collectors.groupingBy(Map.Entry::getValue))
// the map now contains integers mapped to a list of map entries
.entrySet()
.stream()
// sort the stream by descending numeric value
.sorted((o1, o2) -> o2.getKey().compareTo(o1.getKey()))
// use the first four elements of the stream
.limit(4)
.forEach(entry -> System.out.println(entry.getKey() + " " + entry.getValue().stream().map(Map.Entry::getKey).collect(Collectors.joining(", "))));
这导致
32 Mango
18 Grape, Peach
13 Banana
12 Apple, Pear, Orange
答案 1 :(得分:2)
正如我在评论中所说,您需要先撤消地图:Map<String, Integer>
将成为Map<Integer, List<String>>
。
然后,您可以从新地图中检索4个最大键(以前是第一张地图的值)并打印其值
public static <K extends Comparable, V extends Comparable> Map<V, List<K>> reverseMap(Map<K, V> map) {
Map<V, List<K>> result = new HashMap<>();
map.entrySet().stream().forEach((entry) -> {
List<K> lst = result.get(entry.getValue());
if (lst == null) {
lst = new ArrayList<>();
result.put(entry.getValue(), lst);
}
lst.add(entry.getKey());
});
return result;
}
Map<String, Integer> map = new HashMap<>();
map.put("Banana", 13);
map.put("Apple", 12);
map.put("Mango", 32);
map.put("Orange", 12);
map.put("Grape", 18);
map.put("Pear", 12);
map.put("Peach", 18);
Map<Integer, List<String>> flip = reverseMap(map);
flip.entrySet().stream()
.sorted(Map.Entry.<Integer, List<String>>comparingByKey().reversed())
.limit(4)
.forEach(e -> System.out.println(String.join(", ", e.getValue()) + " : " + e.getKey()));
Mango : 32
Grape, Peach : 18
Banana : 13
Apple, Pear, Orange : 12
答案 2 :(得分:1)
只需迭代HashMap
并保留第一个k
元素。
private HashMap<String, Integer> select_k_element(HashMap sortedMap,int k){
HashMap<String, Integer> res=new HashMap();
int i=0;
for (Map.Entry<String, Integer> e : sortedMap.entrySet()) {
String key=e.getKey();
int value=e.getValue();
res.put(key,value);
i++;
if(i>=k)
break;
}
return res;
}
答案 3 :(得分:1)
您必须使用Map
来反转键值对(数据类型)。以下是一个基本实现:
private static Map<String, Integer> fruits = new HashMap<>();
static {
fruits.put("Banana",13);
fruits.put("Apple", 12);
fruits.put("Mango",32);
fruits.put("Orange",12);
fruits.put("Grape",18);
fruits.put("Pear",12);
fruits.put("Peach",18);
}
public static void main(String[] args) {
TreeMap<Integer, String> freq = new TreeMap<>();
// Populate the new Map
fruits.entrySet().forEach(e -> {
Integer key = e.getValue();
if(freq.containsKey(key)) { // Update entry if key is already present
String curVal = freq.get(key);
String newVal = e.getKey();
freq.put(key, curVal + ", " + newVal);
} else { // Add an entry if key is not present
freq.put(key, e.getKey());
}
});
// Print the new Map
freq.descendingMap().entrySet().forEach(e -> {
System.out.println(e.getValue() + " : " + e.getKey());
});
}
使用TreeMap
保持按键排序,并使用descendingMap()
按降序打印。
<强>输出:强>
Mango : 32
Grape,Peach : 18
Banana : 13
Apple,Pear,Orange : 12
答案 4 :(得分:1)
您可以SortedMap使用&#34; Fruit&#34;对象实现Compareable。
地图是根据其键的自然顺序排序的,或者是通常在排序地图创建时提供的比较器。迭代有序映射的集合视图(由entrySet,keySet和values方法返回)时会反映此顺序。提供了几个额外的操作以利用订购。 (此接口是SortedSet的地图模拟。)