web-dev-qa-db-ja.com

LinkedHashMapの実装はHashMapとどのように異なりますか?

LinkedHashMapの時間計算量がHashMapの複雑さと同じである場合、なぜHashMapが必要なのですか? JavaのHashMapと比較した場合、LinkedHashMapの余分なオーバーヘッドはどれくらいですか?

37

LinkedHashMapはより多くのメモリを消費します。通常のHashMapの各エントリには、キーと値があります。各LinkedHashMapエントリには、次および前のエントリへの参照および参照があります。通常は関係ありませんが、やるべきハウスキーピングももう少しあります。

33
Jon Skeet

LinkedHashMapの時間計算量がHashMapの複雑さと同じである場合、なぜHashMapが必要なのですか?

複雑さとパフォーマンスを混同しないでください。 2つのアルゴリズムは同じ複雑さを持つことができますが、一方は他方よりも一貫して優れたパフォーマンスを発揮できます。

f(N) is O(N)は次のことを意味することに注意してください。

C1*N <= limit(f(N), N -> infinity) <= C2*N  

どこ C1およびC2は厳密に正の定数です。複雑さは、C値がどれほど小さいか大きいかについては何も言いません。 2つの異なるアルゴリズムの場合、定数はほとんどの場合differentになります。

(そして、big-Oの複雑さは、Nが非常に大きくなるときの動作/パフォーマンスに関するものであることを忘れないでください。小さなN値の動作/パフォーマンスについては何もわかりません。)


そうは言っても、同等のユースケースでのHashMap操作とLinkedHashMap操作のパフォーマンスの違いは比較的小さいです。多くの場合、より関連性の高い追加のメモリオーバーヘッド。

24
Stephen C
  • LinkedHashMapはさらに、そのすべてのエントリを介して実行される二重リンクリストを維持し、再現可能な順序を提供します。このリンクリストは、反復順序を定義します。これは通常、キーがマップに挿入された順序(挿入順序)です。
  • HashMapにはこれらの追加コスト(実行時間、スペース)がないため、挿入順序を気にしない場合はLinkedHashMapよりも優先する必要があります。
13
stacker

LinkedHashMapは、マップへのキーの挿入順序を知る必要がある場合に役立つデータ構造です。適切な使用例の1つは、LRUキャッシュの実装です。 LinkedHashMapの順序が維持されるため、データ構造にはHashMapと比較して追加のメモリが必要です。挿入順序が必須ではない場合は、常にHashMapを使用する必要があります。

7
Snehal

HashMapとLinkedHashMapの間にはもう1つの大きな違いがあります:LinkedHashMapの場合、反復はより効率的です。

LinkedHashMapの要素は相互に接続されているため、反復には、容量に関係なく、マップのサイズに比例した時間が必要です。ただし、HashMap;の場合決まった順序がないため、反復には容量に比例した時間が必要です。

blog に詳細を記載しました。

5
rai.skumar

HashMapは挿入順序を維持しないため、二重リンクリストを維持しません。

LinkedHashMapの最も顕著な特徴は、キーと値のペアの挿入順序を維持することです。 LinkedHashMapは、そのために二重リンクリストを使用します。

LinkedHashMapのエントリは次のようになります。

  static class Entry<K, V> {
     K key;
     V value;
     Entry<K,V> next;
     Entry<K,V> before, after;        //For maintaining insertion order    
     public Entry(K key, V value, Entry<K,V> next){
         this.key = key;
         this.value = value;
         this.next = next;
     }
  }

Beforeとafterを使用することにより、LinkedHashMapに新しく追加されたエントリを追跡します。これは、挿入順序を維持するのに役立ちます。

前のエントリを参照する前と後はLinkedHashMapの次のエントリを参照します。

図とステップバイステップの説明については、 http://www.javamadesoeasy.com/2015/02/linkedhashmap-custom-implementation.html を参照してください。

2
Ankit Mittal

LinkedHashMapはHashMapを継承します。つまり、HashMapの既存の実装を使用して、キーと値をNode(Entry Object)に格納します。これ以外に、挿入順序を維持するために、別個の二重リンクリスト実装を格納します。キーが入力されている。

それはこのように見えます:

ヘッダーノード<--->ノード1 <--->ノード2 <--->ノード3 <---->ノード4 <--->ヘッダーノード。

したがって、余分な過負荷は、この二重にリンクされたリストでの挿入と削除を維持しています。利点は次のとおりです。反復順序は、HashMapにはない挿入順序であることが保証されています。

1
punitusingh
  • 内容を新しいテーブル配列に転送するために二重リンクリストを反復処理するため、サイズ変更はより高速になるはずです。
  • containsValue()は、より高速なイテレータを利用するためにオーバーライドされます。
  • LinkedHashMapを使用して、LRUキャッシュを作成することもできます。特別なLinkedHashMap(capacity、loadFactor、accessOrderBoolean)コンストラクターが提供され、反復の順序が、エントリが最後にアクセスされた順序(最近アクセスされた順序から最近アクセスされた順序)になります。この場合、get()を使用してマップをクエリするだけで、構造が変更されます。
0
Satish