我有一张这样的地图
Map<String, Integer> map = new HashMap<String, Integer>();
这将包含大量的推文,而我想要做的就是制作一些前5名的统计数据。
我现在拥有的是
int maxValueInMap=(Collections.max(map.values()));
for (Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue()==maxValueInMap) {
name = entry.getKey();
}
}
这对于获取地图中数字1最高值的键/值非常有用,但我无法弄清楚我如何能够获得前五名的最高值并具有类似
的内容int maxValueInMap=(Collections.max(map.values()));
for (Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue()==maxValueInMap) {
name = entry.getKey();
name2 = entry.getKey(2ndHighest);
//so on
}
}
感谢任何帮助,谢谢。
修改
我发现这段代码的功能就像它希望的那样
public class Main {
public static void main(String[] args) {
HashMap<String,Integer> map = new HashMap<String,Integer>();
ValueComparator bvc = new ValueComparator(map);
TreeMap<String,Integer> sorted_map = new TreeMap<String,Integer>(bvc);
map.put("a",10);
map.put("b",6);
map.put("c",6);
map.put("d",56);
map.put("e",54);
map.put("f",32);
map.put("g",1);
System.out.println("unsorted map: "+map);
sorted_map.putAll(map);
System.out.println("results: "+sorted_map);
}
}
class ValueComparator implements Comparator<String> {
Map<String, Integer> base;
public ValueComparator(Map<String, Integer> base) {
this.base = base;
}
public int compare(String a, String b) {
if (base.get(a) >= base.get(b)) {
return -1;
} else {
return 1;
}
}
}
打印出来
unsorted map: {a=10, b=6, c=6, d=56, e=54, f=32, g=1}
results: {d=56, e=54, f=32, a=10, c=6, b=6, g=1}
但是我怎样才能从sorted_map而不是所有的部分中获得前5名?
答案 0 :(得分:2)
您希望按值对项目进行排序,默认情况下,这不能在HashMap
或TreeMap
中完成。
您应该考虑拥有自己的课程并使用TreeSet
:
class Entry implements Comparable<? extends Entry> {
public final String name;
public final Integer value;
..
public int compareTo(Entry o) { return value == o.value ? o.name.compareTo(name) : o.value - value; }
public boolean equals(Object o) {
// equals consistent to compareTo (name and value equal for both entries)
}
}
SortedSet<Entry> set = new TreeSet<Entry>();
set.add(...)
答案 1 :(得分:2)
这样做的简单方法是:
然而,排序步骤是O(N log N)
,如果N很大并且您需要重复获得前5个,那么这就是性能杀手......并且可以更新整数值(例如计数)。 / p>
如果您需要更好的性能,则需要更复杂的数据结构,以允许增量更新(以避免重新排序):
如果您将自己限制在标准集合类中,可以使用以下方法完成此操作:
Pair
课程。HashMap<String, Pair>
。TreeSet<Pair>
。 Pair
同一性对其进行排序。 (后者很重要。比较器不能将Pair
个对象计为相同的计数,否则Pair
个对象将被错误地删除为重复!)。您记得的最后一件事是,如果您只更改TreeSet
中的count
,Pair
将无法自动正确更新。相反,你需要:
Pair
TreeSet
count
Pair
添加回TreeSet
。其余的是“只是编程”。 (但对我来说,现在编写,编译,测试等太复杂了:-))
如果您正确执行上述操作,则添加或递增计数应为O(log N)
,并且查找前5个条目应为O(1)
。但是,由于您使用它作为O(1)
添加/增加的解决方案的替代品,如果N
很大(足够)并且“前5”是相对的,这只是一个明显的性能获胜常见的操作。
还值得注意的是,您还可以在M
中未排序的N
元素集合中获取前O(N log M)
个元素。如果M
是一个小常量,则会减少到O(N)
。换句话说,它比在顶部简单版本中对条目集进行排序更好。 (小N
也可能更快。)
回答这个后续问题:
但是我怎样才能从sorted_map中获得前5名,而不是所有的主语?
创建一个迭代器,然后只调用next()
5次!
但我还要注意,您找到的代码是 INCORRECT 。我强烈建议您自己编写代码并对其进行全面测试。 (或者将您的搜索限制在包含合适的单元测试套件的可信库中。)