5

元のデータは次のようになります。

String data = "{ \"a\":1, \"b\":3 , \"c\":-1 }";

私の最初のステップは、それを HashMap に変換することです。

Gson gson = new Gson();
HashMap<String, Double> map = gson.fromJson(data, HashMap.class);

次に、キーを値で並べ替えます。

public static List<String> sortHashMap(final HashMap<String, Double> map) {
    Set<String> set = map.keySet();
    List<String> keys = new ArrayList<String>(set);

    Collections.sort(keys, new Comparator<String>() {

        @Override
        public int compare(String s1, String s2) {
            if (map.get(s1) < map.get(s2)) {
                return 1;
            }
            return 0;
        }
    });

    return keys;
}

最後に、上位 N 個のキーを取得します。

keys.subList(0, N);

最終的に結果が得られますが、エレガントな方法ではないと思います。

何か便利な作り方はないのかな?

4

2 に答える 2

5

よりエレガントでスケーラブルなアプローチは、サイズが N に制限されているプラ​​イオリティ キューを使用することです。最小ヒープ プライオリティ キューを使用すると、サイズが N に達するまでキューにエントリを追加し続けることができます。優先度キューが N に達した場合、それをキューに追加し、キューの先頭にある要素 (最小値を持つ) を削除します。HashMap からすべてのエントリを使い果たした後、キューには上位 N エントリが含まれます。

このアプローチの利点は、HashMap 全体がメモリに収まらない場合でも、小さなブロックに分割してこのアプローチを使用できることです。また、同時優先キューがある場合は、異なる HashMap から同時にエントリをキューに追加することもできます。

public static List<String> topNKeys(final HashMap<String, Double> map, int n) {
    PriorityQueue<String> topN = new PriorityQueue<String>(n, new Comparator<String>() {
        public int compare(String s1, String s2) {
            return Double.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());
}
于 2015-01-10T01:49:33.803 に答える
3

あなたがしたことはOKです。カスタム Comparator をどこかに記述する必要があり、それを使用した場所は問題ありません。

ただし、メソッドにバグがありますcompare()。s1 > s2 の場合は 0 を返しますが、数値が等しい場合にのみそれを行い、s1 > s2 の場合は負の数を返す必要があります。以下の実装はそれを修正します。

より良い(そしてより簡単な)実装は次のとおりです。

 public int compare(String s1, String s2) {
     return Double.compare(map.get(s2), map.get(s1)); //reverse order
 }
于 2013-09-24T02:37:30.770 に答える