目次
Javaコレクションの概要
図からわかるように、Javaに加えてMap
、クラスの終わり以外に、他のクラスがCollection
インターフェースを実装しています。そして、Map
クラスの最後にMap
インターフェースを実装します。
Javaコレクションの基礎となるデータ構造の要約
1.リスト
保存された要素は順序付けられ、繰り返し可能です。
Arraylist
:Object[]
配列Vector
:Object[]
配列LinkedList
:二重リンクリスト(JDK1.6より前の循環リンクリスト、JDK1.7はサイクルをキャンセルします)
2.セット
保存された要素は順序付けられておらず、繰り返すことはできません。
HashSet
:無秩序に、HashMap
実装に基づく唯一のHashMap
要素は要素を保存することに基づいていますLinkedHashSet
:LinkedHashSet
それはHashSet
サブクラスであり、LinkedHashMap
達成された内部を通してです。LinkedHashMap
そのインテリアにやや似ているのHashMap
は、同じことの実現に基づいていますTreeSet
:注文された、ユニークな赤黒木
3.マップ
HashMap
:JDK1.8以前はHashMap
、配列+リンクリストで構成されていました。配列がHashMap
本体であり、リンクリストは主にハッシュ競合の存在を解決するためのものです。JDK1.8以降、ハッシュの競合の解決に変更が加えられました。リンクリストの長さがしきい値(デフォルトは8)より大きい場合、リンクリストは検索時間を短縮するために赤いツリーに変換されます。LinkedHashMap
:LinkedHashMap
selfを継承するHashMap
ため、その最下層は引き続き配列とリンクリスト/赤いツリーに基づいています。さらにLinkedHashMap
、上記の構造に基づいて、二重にリンクされたリストが追加され、上記の構造がキーと値のペアの挿入順序を維持できるようになります。同時に、リンクリストの対応する操作を通じて、アクセスシーケンス関連のロジックが実現されます。Hashtable
:+配列で構成されるリスト、配列はHashtable
サブジェクト、リストは主にハッシュ衝突を解決するためのものですTreeMap
:赤黒木
HashMapとHashtableの違い
1.スレッドは安全ですか?
HashMap
スレッドセーフではありません。
HashTable
HashTable
基本的な内部のメソッドがsynchronized
変更されているため、スレッドセーフです。
2.効率
少し高効率HashMap
よりもスレッドセーフの問題がHashTable
あるからです。また、HashTable
基本的には削除されているので、コードでは使用しないでください。
3.NullキーとNull値のサポート
HashMap
nullキーと値を格納できますが、キーとして存在できるnullは1つだけであり、値として存在できるnullは複数あります。
HashTable
nullキーとnull値は許可されていません。許可されていない場合はスローされNullPointerException
ます。
4.初期容量
作成時に容量の初期値を指定しない場合
HashMap
デフォルトの初期化サイズは16です。拡張するたびに、容量は2倍になります。
Hashtable
デフォルトの初期サイズは11で、各拡張後、容量は元の2n +1になります。
5.毎回容量を拡張します
作成時に容量の初期値が指定されている場合
HashMap
2倍に拡大します
Hashtable
あなたが与えたサイズを直接使用します
6.基礎となるデータ構造
JDK1.8以降HashMap
、ハッシュの競合の解決に変更が加えられました。リンクリストの長さがしきい値(デフォルトは8)を超えると、リンクリストは赤黒木に変換されて検索時間が短縮されます。
デフォルト値が8である理由を追加します。8の場合、赤黒木の平均検索長はlog(N)= 3であり、リンクリストの平均検索長は8/2 = 4です。
そのHashtable
ようなメカニズムはありません。
HashMapとHashSetの違い
HashSet
これは、基盤となるHashMap
実装に基づいています。HashSet
加えためのソースコードは、非常に僅かでありclone()
、writeObject()
、readObject()
あるHashSet
実装すること自体の外側が、他の方法は、直接呼び出されるHashMap
方法。
HashMap | HashSet |
---|---|
マップインターフェイスを実装しました | Setインターフェースを実装する |
キーと値のペアを格納する | オブジェクトのみを保存する |
put()を呼び出して、マップに要素を追加します | add()メソッドを呼び出して、要素をセットに追加します |
HashMapはKeyを使用してハッシュコードを計算します | HashSetは、メンバーオブジェクトを使用してハッシュコード値を計算します。2つのオブジェクトの場合、ハッシュコードは同じである可能性があるため、equals()メソッドを使用してオブジェクトの同等性を判断します。 |
ConcurrentHashMapとHashtableの違い
ConcurrentHashMap
そしてHashtable
、その違いは主にスレッドセーフを実現するためのさまざまな方法に反映されています。
1.基礎となるデータ構造
JDK1.7は、ConcurrentHashMap
基になる配列+ピースワイズリンクリストの実装であり、JDK1.8HashMap
構造1.8で使用されるデータ構造は、配列リスト+ /赤と黒の二分木です。
Hashtable
また、JDK1.8より前は、HashMap
同様の基礎となるデータ構造が配列+リストの形式で使用されていました。
2.スレッドセーフを実現する方法
JDK1.7はConcurrentHashMap
、セグメント化されたロックによってスレッドセーフを実現します。まず、バケット配列全体がセグメント化されます。各ロックは、コンテナ内のデータの一部のみをロックします。コンテナ内の異なるデータセグメントにマルチスレッドでアクセスする場合、ロックの競合は発生しません。同時アクセス率を向上させます。
JDK1.8ConcurrentHashMap
は、セグメントの概念を放棄しますが、直接リンクされたリストデータ構造ノード配列++同時実行制御synchronized
を使用して実装された赤黒木とCASを操作します。synchronized
電流のみチェーンをロックするか、最初のノードは、ツリー、スレッドセーフおよび最適化のような全体の外観、黒、赤HashMap
Hashtable
のみロックを有していた全体のハッシュテーブルに相当するフル・テーブル・ロックによるスレッドの安全性を達成するために、get
/put
すべての操作をすべてsynchronized
です。マルチスレッドアクセスでは、1つのスレッドがオブジェクトにアクセスまたは操作すると、他のスレッドはブロック状態またはポーリング状態にしか入ることができません。たとえば、スレッドがput
追加された要素を使用する場合、他のスレッドはput
追加された要素を使用できず、使用することもできずget
、並行シナリオではパフォーマンスが非常に低下します。
補足:ArraylistとLinkedListの違い
1.スレッドセーフを確保するかどうか
ArrayList
またLinkedList
、同期されていません。スレッドセーフであるとは限りません。
しかし、それVector
はスレッドセーフです。
2.基礎となるデータ構造
Arraylist
二重リンクリストデータ構造を使用した最下位Object
配列
LinkedList
アンダーレイヤーの使用(JDK1.6循環リンクリストの前と同様に、JDK1.7はサイクルをキャンセルしました)。
3.挿入と削除は要素の位置の影響を受けますか
ArrayList
配列ストレージが使用されるため、要素の挿入と削除の時間計算量は、要素の位置に影響されます。たとえば、add(E e)
メソッドを実行するとArrayList
、指定された要素がデフォルトでリストの最後に追加されます。この場合、時間計算量はO(1)です。ただし、指定した位置i(add(int index, E element)
)で要素を挿入および削除する場合、時間計算量はO(ni)です。上記の操作では、セット内のi番目の要素の後のi番目と(ni)の要素を1ビット前後に移動する必要があるためです。
LinkedList
リンクリストストレージが使用されるため、add(E e)
メソッドの挿入では、要素の削除の時間計算量は要素の位置(約O(1)の影響を受けません)。指定された位置i((add(int index, E element)
)で要素を挿入および削除する場合時間計算量は約o(n))です。挿入する前に、指定された位置に移動する必要があるためです。
4.高速ランダムアクセスをサポートするかどうか
ArrayList
高速ランダムアクセスをサポートします。高速ランダムアクセスは、要素のシーケンス番号を介して要素オブジェクト(get(int index)
メソッドに対応)をすばやく取得することです。
LinkedList
効率的なランダム要素アクセスはサポートしていません。
5.メモリフットプリント
ArrayList
スペースの浪費は主にリストの最後にあるリストに
LinkedList
反映されますスペースの容量は予約されますスペースの容量は、よりArrayList
多くのスペースを消費する必要がある各要素に反映されます(直接のデポジットと直接の先行および後続のため)データ)。
参照:
https://github.com/Snailclimb/JavaGuide
https://www.cnblogs.com/chengxiao/p/6842045.html