英文:
How to get the 3 highest values in a HashMap?
问题
以下是翻译好的内容:
我有一个哈希映射,如下所示:
HashMap<String, Integer> hm = new HashMap<String, Integer>();
hm.put("a", 1);
hm.put("b", 12);
hm.put("c", 53);
hm.put("d", 2);
hm.put("e", 17);
hm.put("f", 8);
hm.put("g", 8);
我要如何获取具有最高三个值的键?这将返回:
"c", "e", "b"
谢谢。
英文:
I have a hashmap which is the following:
HashMap<String, Integer> hm = new HashMap<String, Integer>;
hm.put("a", 1);
hm.put("b", 12);
hm.put("c", 53);
hm.put("d", 2);
hm.put("e", 17);
hm.put("f", 8);
hm.put("g", 8);
How would I get the keys which have the 3 highest values? So it would return:
"c", "e", "b"
Thanks.
答案1
得分: 12
List<String> keys = hm.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).limit(3).map(Map.Entry::getKey).collect(Collectors.toList());
英文:
My solution, sort by values and get top 3 and return key list.
List<String> keys = hm.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).limit(3).map(Map.Entry::getKey).collect(Collectors.toList());
Hope it helps
答案2
得分: 4
这段代码是要描述一个性能更好但难以阅读的实现方式。如果你了解PriorityQueue
的工作原理,这将变得相对简单:它在任何给定时间点只保留n + 1
个元素。随着元素的添加,最小的元素逐个被移除。
当这个过程完成后,我们将元素插入到一个数组中,但是顺序是反向的(因为PriorityQueue
只保持其头部有序,或者头部始终根据Comparator
是最大值/最小值)。
你甚至可以将其泛化,或者使用流创建一个自定义的收集器来实现这一功能。
英文:
This is a lot harder to read, but will perform a lot better:
public static List<String> firstN(Map<String, Integer> map, int n) {
PriorityQueue<Entry<String, Integer>> pq = new PriorityQueue<>(
n + 1, Map.Entry.comparingByValue()
);
int bound = n + 1;
for (Entry<String, Integer> en : map.entrySet()) {
pq.offer(en);
if (pq.size() == bound) {
pq.poll();
}
}
int i = n;
String[] array = new String[n];
while (--i >= 0) {
array[i] = pq.remove().getKey();
}
return Arrays.asList(array);
}
If you know how a PriorityQueue
works, this is rather trivial: it keeps only n + 1
elements at any given point in time. As elements are being added, the smallest element is removed, one by one.
When this is done, we insert elements into an array, but in reverse order (because a PriorityQueue
keeps sorted only its head or the head is always max/min according to the Comparator
).
You can even make this generic, or create a custom collector with streams for this.
答案3
得分: 1
这是我的看法:这只追踪TreeSet中排名靠前的n个项目。
import java.util.*;
import java.util.stream.Collectors;
public class TopN {
public static <E> Collection<E> topN(Iterable<E> values, Comparator<? super E> comparator, int n) {
NavigableSet<E> result = new TreeSet<>(comparator.reversed());
for (E value : values) {
result.add(value);
if (result.size() > n) {
result.remove(result.last());
}
}
return result;
}
public static void main(String[] args) {
Map<String, Integer> hm = Map.of(
"a", 1,
"b", 12,
"c", 53,
"d", 2,
"e", 17,
"f", 8,
"g", 8);
List<String> result = topN(hm.entrySet(), Map.Entry.comparingByValue(), 3)
.stream()
.map(Map.Entry::getKey)
.collect(Collectors.toList());
System.out.println(result);
}
}
最终输出为[c, e, b]
。
英文:
Here's my take on it: This keeps track of only the top n items in a TreeSet.
import java.util.*;
import java.util.stream.Collectors;
public class TopN {
public static <E> Collection<E> topN(Iterable<E> values, Comparator<? super E> comparator, int n) {
NavigableSet<E> result = new TreeSet<>(comparator.reversed());
for (E value : values) {
result.add(value);
if (result.size() > n) {
result.remove(result.last());
}
}
return result;
}
public static void main(String[] args) {
Map<String, Integer> hm = Map.of(
"a", 1,
"b", 12,
"c", 53,
"d", 2,
"e", 17,
"f", 8,
"g", 8);
List<String> result = topN(hm.entrySet(), Map.Entry.comparingByValue(), 3)
.stream()
.map(Map.Entry::getKey)
.collect(Collectors.toList());
System.out.println(result);
}
}
The final output is [c, e, b]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论