1

エントリをチェックHashMapしてから置き換えたいとします。

if( check( hashMap.get(key) ) ) {
    hashMap.put(key, newValue);
}

これにより、内部の検索手順HashMapが 2 回実行されます。1 回は whilegetで、もう 1 回は whileputです。これは効果がないように見えます。マップの既に見つかったエントリの値を変更することは可能ですか?

アップデート

ラッパーを作成できることはわかっていますが、エントリを変更するのに問題があることもわかっています。しかし、問題はなぜですか?繰り返しHashMapの検索を改善するために、最後の検索を覚えているのでしょうか? なぜそのような操作を行う方法がないのですか?

4

4 に答える 4

3

編集:私はあなたが経由でエントリを変更できることMap.Entry.setValueを発見しました(そしてHashMap実装は変更可能です)。ただし、特定のキーのエントリを取得するのは面倒であり、誰かがこれを行うのを見たことはありません。エントリのセットを取得することはできますが、私が知る限り、単一のキーのエントリを取得することはできません。

それを行うには1つの邪悪なHashMap方法があります-パッケージ内の独自のサブクラスを宣言し、パッケージに委任するだけのパブリックメソッドをjava.util作成します-プライベート既存のメソッド:

package java.util;

// Please don't actually do this...
public class BadMap<K, V> extends HashMap<K, V> {
    public Map.Entry<K, V> getEntryPublic(K key) {
        return getEntry(key);
    }
}

しかし、それはかなり厄介です。

通常はエントリを変更しませんが、可変タイプの場合はもちろん、値内のデータを変更できます。

ただし、これを大量に実行しない限り、これが実際にはパフォーマンスのボトルネックであるかどうかは非常に疑わしいです。おそらく問題ではない何かを微調整しようとする前に、これが実際の問題であることを自分自身に証明するために、アプリケーションのプロファイルを作成する必要があります。

それ問題であることが判明した場合は、(たとえば)aMap<Integer, String>をaに変更し、単純な可変ラッパータイプとしてMap<Integer, AtomicReference<String>>使用できます。AtomicReference<T>

于 2013-01-24T20:50:13.013 に答える
2

あなたの質問にコメントするには情報が多すぎます。ハッシュマップのドキュメントを確認してください。

この実装は、ハッシュ関数が要素をバケット間で適切に分散すると仮定すると、基本操作 (get および put) に対して一定時間のパフォーマンスを提供します。コレクション ビューの反復には、HashMap インスタンスの「容量」(バケットの数) とそのサイズ (キーと値のマッピングの数) に比例する時間が必要です。したがって、反復のパフォーマンスが重要な場合は、初期容量を高く設定しすぎないようにする (または負荷係数を低く設定しすぎない) ことが非常に重要です。

一定時間とは、get 操作と put 操作 [O(1)] を実行するのに常に同じ時間が必要であることを意味します。必要な時間は、[O(n)] をループする必要がある回数に基づいて線形になります。

于 2013-01-24T21:10:10.147 に答える
1

エントリが変更可能な場合は、エントリを変更できます。これを行う場所の一例は次のとおりです。

private final Map<String, List<String>> map = new LinkedHashMap<>();

public void put(String key, String value) {
    List<String> list = map.get(key);
    if (list == null)
        map.put(key, list = new ArrayList<>());
    list.add(value);
}

これにより、値を更新できますが、1 回の操作で値を見つけて置き換えることはできません。

于 2013-01-24T20:53:22.357 に答える
1

trove ( http://trove4j.sourceforge.net/ ) を見てください。それらのマップには、必要なメソッドがいくつかあります。

  • 調整または配置
  • putIfAbsent

これが内部でどのように実装されているかはわかりませんが、trove は高性能になるように作られているため、ルックアップは 1 回しかないと思います。

于 2013-01-24T21:00:56.583 に答える