获取java

时间:2017-06-15 08:19:33

标签: java

我有一个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个整数。

我怎么能这样做?任何形式的帮助和建议都表示赞赏。

1 个答案:

答案 0 :(得分:2)

你可以分两步完成:

  1. 收集不同的前N个数字
  2. 收集在前N
  3. 中具有值的所有条目

    就代码而言,您可以这样写:

    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;
    }