2

HashMap<String,float[]>. コアコンポーネントがシステムの同時実行性が高いAndroidアプリケーションがあります。たとえば、私が頻繁に発生する次の 3 つの状況は、本質的に非常に重複しています。

  1. ハッシュマップ内のすべてのキーを繰り返し処理し、その値に対して何らかの操作を実行します (読み取り専用操作)。
  2. Hashmap に新しいキーと値のペアを追加します。
  3. ハッシュマップから特定のキーを削除します。

これらすべての操作を異なるスレッドで実行しているため、取得の不一致は問題にならないため、ConcurrentHashMap を使用しています。たとえば、マップを反復しているときに、新しいエントリが追加された場合、それらの新しい値をすぐに読み込まなくても問題ありません。次回は確実に読み込まれるようにするためです。

また、エントリを削除している間、「ConcurrentModificationException」を回避するために毎回イテレータを再作成しています

次のハッシュマップ(つまり、ConcurrentHashmap)があるとします。

ConcurrentHashMap<String,float[]> test=new ConcurrentHashMap<String, float[]>(200);

取得のために、次のことを行います

Iterator<String> reader=test.keySet().iterator();
            while(reader.hasNext())
            {
                String s=reader.next();
                float[] temp=test.get(s);
                //do some operation with float[] temp here(read only operation)
            }

削除するには、次のことを行います

boolean temp = true;
        while (temp) {
            for (String key : test.keySet()) {
                temp = false;
                if (key.contains("abc")) {
                    test.remove(key);
                    temp = true;
                    break;
                }
            }
        }

新しい値を挿入するときは、単純に

test.put("temp value", new float[10]);

それが非常に効率的な利用であるかどうかはわかりません。また、削除された値を読み取らないことも重要です(ただし、効率が必要ですが、関数呼び出し中にイテレータが再度作成されるため、次回は削除された値を取得しないことが保証されます)。許容?

どなたか効率の良い方法を教えてください。

PS。なぜ私がそのような方法で除去操作を行っているのかを言い忘れていました。equal から contains に削除される条件を変更しました (接頭辞「abc」の後に異なる接尾辞が続く文字列が複数ある可能性があります。そのため、それらすべてを削除する必要があります。

4

3 に答える 3

2

の使用方法により、その特性ConcurrentHashMapを正確に削除しています。Concurrent(再)同期の試みは非常に頻繁に機能しますが、常に機能するとは限りません。

を に残すことを検討しkeysましたHashMapか? 私は次のようなことを考えています:

    public static final float[] DELETED= new float[0] ;

    /* delete */
    test.put(key,DELETED);

    /* insert */
    test.put(key,value);

    /* iterate */
    for(Map.Entry<String,float[]> e: test.entrySet ) {
        if( e.getValue() != DELETED ) {
            operateOn(e);
        }
    }

キーが不安定すぎる場合 (つまり、しばらくすると DELETED アイテムが多すぎる場合)、 cleanup を作成できますThread

于 2013-09-01T05:45:41.203 に答える
0

ConcurrentHashMap API によると、イテレータは ConcurrentModificationException をスローしないため、削除後に中断する必要はありません。しかし、いずれにせよ、反復して削除する正しい方法はこれです

for (Iterator<String> i = test.keySet().iterator(); i.hasNext();) {
     String next = i.next();
     if (next.equals("abc")) {
             i.remove();
     }
}

このようにして、ConcurrentModificationException のないフェイルファスト イテレーターでも機能します。

于 2013-09-01T05:46:30.967 に答える