-1

私はJavaを初めて使用します。同時ハッシュマップを値で並べ替えたい。私はここでそれを行う方法を見つけました- 同時マップエントリを値で並べ替えます

それを行うためのより簡単な方法はありますか?誰かが例を挙げて説明してもらえますか?

ありがとう。

4

3 に答える 3

4

別の解決策は、Java 6で追加されたを使用するように切り替えることConcurrentSkipListMapです。Javadocから引用するには:

このクラスは、SkipListsの並行バリアントを実装し、containsKey、get、put、およびremove操作とそのバリアントの予想平均log(n)時間コストを提供します。挿入、削除、更新、およびアクセス操作は、複数のスレッドによって同時に安全に実行されます。イテレータは一貫性が低く、イテレータの作成時または作成後のある時点でのマップの状態を反映する要素を返します。これらはConcurrentModificationExceptionをスローせず、他の操作と同時に続行する場合があります。昇順のキー順ビューとそのイテレータは、降順のビューよりも高速です。

SkipListsは、バランスの取れたツリーの確率的な置換です。それらはOツリーと同じですが、通常、それらの実装は著しく単純です。ほとんどの操作が(O(1)定義上)ハッシュテーブルルックアップである場合、適切なテーブルサイズではパフォーマンスが異なりますが、頻繁に並べ替える必要がある場合は、これがより良い解決策になる可能性があります。

Javaがこの優れたデータ構造の非並行バージョンを提供してくれることを願っています。

于 2012-05-15T01:10:43.707 に答える
2

ユースケースに応じて、ハッシュマップと値の順序を維持するためのリストで構成されるデータ構造を表す別のクラスを作成します。

詳細については、こちらをご覧ください:
Map <Key、Value>を値で並べ替える(Java)
HashMapを値で並べ替える
http://www.coderanch.com/t/382750/java/java/Sorting-HashMap-values

ConcurrentHashMapを拡張して、entrySetメソッドとkeySetメソッドをオーバーライドし、値の順序でエントリ/キーを返すこともできます。

public class OrderedValueHashMap<K,V extends Comparable<V>> extends ConcurrentHashMap<K, V> {

@Override
public Set<Map.Entry<K, V>> entrySet() {
    Set<Map.Entry<K, V>> orderedValueEntrySet = new TreeSet<Map.Entry<K,V>>(new Comparator<Map.Entry<K,V>>() {

        @Override
        public int compare(java.util.Map.Entry<K, V> o1,
                java.util.Map.Entry<K, V> o2) {
            return o1.getValue().compareTo(o2.getValue());
        }
    });
    orderedValueEntrySet.addAll(super.entrySet());
    return orderedValueEntrySet;
}

@Override
public Set<K> keySet() {
    Set<K> orderedKeySet = new LinkedHashSet<K>();
    for(Map.Entry<K, V> e : entrySet()) {
        orderedKeySet.add(e.getKey());
    }
    return orderedKeySet;
}

}

上記のソリューションは、keySet / entrySetメソッドを頻繁に呼び出す場合、呼び出しごとにエントリを並べ替えるため、最適ではありません。マップの内部状態が変更されていないときに再計算を回避するために、これらの結果をキャッシュすることをお勧めします。

上記の実行例は次のとおりです。

public static void main(String[] args) {
    ConcurrentHashMap<String,Integer> map = new OrderedValueHashMap<String,Integer>();
    map.put("a", 3);
    map.put("b", 7);
    map.put("c", 1);
    map.put("q", 2);

    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        System.out.println(entry);
    }

    for (String key : map.keySet()) {
        System.out.println(key);
    }

}

出力:

c=1
q=2
a=3
b=7
c
q
a
b
于 2012-05-14T23:08:31.640 に答える
1

それを行うためのより簡単な方法はありますか?

私の知る限り、いいえ。

確かに、インプレースソートの同時ハッシュマップを実行する方法はありません。CHMは本質的に順序付けされていないため、エントリの順序を表すために、エントリを別のデータ構造に配置する必要があります。

要件を教えていただければ、別の戦略を提案できるかもしれません。

于 2012-05-14T22:58:37.913 に答える