我有一个HashMap结果数据,如下所示
"zip000", 1234
"zip001", 2345
"zip002", 3456
"zip003", 4567
"zip004", 7890
"zip005", 7890
"zip006", 123
"zip007", 234
"zip010", 7890
"zip011", 678
"zip012", 789
"zip013", 890
并在代码
下面使用 public static List<String> topNKeys(final HashMap<String, Integer> map, int n) {
PriorityQueue<String> topN = new PriorityQueue<String>(n, new Comparator<String>() {
public int compare(String s1, String s2) {
return Integer.compare(map.get(s1), map.get(s2));
}
});
for(String key:map.keySet()){
if (topN.size() < n)
topN.add(key);
else if (map.get(topN.peek()) < map.get(key)) {
topN.poll();
topN.add(key);
}
}
return (List) Arrays.asList(topN.toArray());
}
以上代码将topN记录显示为
假设n = 6
zip001=2345
zip002=3456
zip003=4567
zip005=7890
zip010=7890
zip004=7890
但我需要根据整数排名给出所有前6名结果数据,我的意思是如下所示
zip013=890
zip000=1234
zip001=2345
zip002=3456
zip003=4567
zip005=7890
zip010=7890
zip004=7890
根据整数,其中7890,4567,3456,2345,1234,890是前5个整数。
我怎么能这样做?任何形式的帮助和建议都表示赞赏。
答案 0 :(得分:2)
你可以分两步完成:
就代码而言,您可以这样写:
public static List<Entry<String, Integer>> topNKeys(Map<String, Integer> map, int n) {
Set<Integer> topValues = getTopValues(map, n);
return getEntriesWithTopValues(map, topValues);
}
//Returns the distinct top n values
private static Set<Integer> getTopValues(Map<String, Integer> map, int n) {
TreeSet<Integer> values = new TreeSet<>(map.values());
Set<Integer> topNValues = new HashSet<>();
for (int i = 0; i < n; i++) {
Integer v = values.pollLast();
if (v != null) topNValues.add(v);
else break;
}
return topNValues;
}
//Returns the entries with a value that is contained in topValues
private static List<Entry<String, Integer>> getEntriesWithTopValues(Map<String, Integer> map, Set<Integer> topValues) {
return map.entrySet().stream()
.filter(e -> topValues.contains(e.getValue()))
.sorted(Entry.comparingByValue())
.collect(toList());
}
应用于您的示例,它返回所需的输出。
没有流,可以编写最后一个方法:
private static List<Entry<String, Integer>> getEntriesWithTopValues(Map<String, Integer> map, Set<Integer> topValues) {
List<Entry<String, Integer>> result = new ArrayList<> ();
for (Entry<String, Integer> e : map.entrySet()) {
if (topValues.contains(e.getValue())) result.add(e);
}
Collections.sort(result, new Comparator<Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
return e1.getValue().compareTo(e2.getValue());
}
});
return result;
}