HashSetソースコード解析は面接問題から、HashSet内部はどのように実現されていますか?
本明細書のオリジナルアドレス、
前言
この間、友达の面接でこの問題に遭遇しました.HashSetの特徴について話します.それはどのように実現されていますか.使用するときに注意しなければならない点は何ですか.ちょうど最近この方面の文章を書いているので、ちょうどこの文章を通じて
友情リンク:HashMapソースコードの全解析面接問題から:hashmap put方法を1行1行コードで説明してください
HashSet構造の詳細
クラス構造
関係図に注意すべき点はなく、
クラスメンバー
先に述べたように、Set内部に重複要素は存在しないが、HashSet内部はどのようにしているのだろうか.図のように、直接HashMapを使用してデータを保存します.HashMapのKeyは唯一でなければならないので、私たちが保存する必要があるデータをKeyに置くことができます.すべてのvalueは1つの内部のオブジェクトPRESENTに対応しています.
ソースの詳細
コンストラクタ
簡単明瞭で、HashMapを直接newします.ここで注意しなければならないのは、もう一つの一般的ではない構造方法です.
この構成方法を使用すると、内部ではHashMap操作要素ではなく
add(E e)要素の追加
HashMapのputメソッドを直接呼び出し、要素eをmapのkey位置に配置して一意性を保証します.HashMapのputメソッドは,この位置に同じKey(==またはequals等しい)が既に存在する場合,元の古いvalueを新しいvalueで置き換え,古いvalueを返すことを知っているので,HashSetにとって最初の挿入はnullを返すことに成功し,後で同じ要素を再び挿入し,戻るのはオブジェクトであり,このような要素がすでに存在していることを示している.挿入に失敗しました.他のremoveではcontainsメソッドが似ています.
注意点 HashSetに格納されている要素はすべて「無秩序」であり、下位層は配列実装を使用し、格納時にkeyをhashして配列位置を導出するため、ランダムなプロセスであるため、格納されている要素は無秩序である. HashSet反復時のパフォーマンスを考慮すると、初期容量はできるだけ小さく設定できますが、ロードプライマーは大きく設定できます(デフォルト0.75).HashSetとHashMapの注目の中心が異なるため、HashMapはその中のキー値ペアの記憶および拡張時の性能の考慮に注目している.HashSetの反復メソッドは、HashMap内部のKeySetのiteratorメソッドを直接呼び出し、
この方法は反復時に配列がnullであるか否かをループ判定し,nullでない場合にはその位置に要素があると考える.したがって、初期容量を決定するには、HashSet反復のkeyをできるだけ小さく設定することが有利である.
まとめ HashSetは、要素が重複せず無秩序な容器である. HashSetの内部ではHashMapを使用して実装され、つまり最終的には配列を使用してデータを格納する. 使用時には、できるだけ容器の大きさを決定し、できるだけ初期容量を小さく設定し、ロードリードを大きくして反復性能を速める必要があります.
関連記事:HashMapソースコードの全解析面接問題から:hashmap putメソッドjdk 1.8ソースコード解析-ARayList jdk 1.8 LinkedListソースコードの全分析スレッドプールを1行1行説明してください.面接?これを見れば十分だ.
:https://jsbintask.cn/2019/03/27/jdk/jdk8-hashset/(食用効果が最も良い)、転載は出典を明記してください!前言
この間、友达の面接でこの問題に遭遇しました.HashSetの特徴について話します.それはどのように実現されていますか.使用するときに注意しなければならない点は何ですか.ちょうど最近この方面の文章を書いているので、ちょうどこの文章を通じて
HashSet
のソースコードの実現を説明して、注意しなければならない点です.HashSet
はSet
インターフェースを実現し、重複要素を格納できない容器であり、内部はHashMap
を直接使用して実現される.すなわち、下層は配列を使用してデータを格納し、HashSetは同期手段がなく、マルチスレッド環境では慎重に考慮し、Collections.synchronizedSet(new HashSet(...));
を使用して従来のSetメソッドに同期することができる.友情リンク:HashMapソースコードの全解析面接問題から:hashmap put方法を1行1行コードで説明してください
HashSet構造の詳細
クラス構造
関係図に注意すべき点はなく、
HashSet
はSet
インターフェースを実現し、Setは
の抽象概念であり、その内部に重複する要素が現れることは許されない.クラスメンバー
先に述べたように、Set内部に重複要素は存在しないが、HashSet内部はどのようにしているのだろうか.図のように、直接HashMapを使用してデータを保存します.HashMapのKeyは唯一でなければならないので、私たちが保存する必要があるデータをKeyに置くことができます.すべてのvalueは1つの内部のオブジェクトPRESENTに対応しています.
ソースの詳細
コンストラクタ
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
簡単明瞭で、HashMapを直接newします.ここで注意しなければならないのは、もう一つの一般的ではない構造方法です.
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
この構成方法を使用すると、内部ではHashMap操作要素ではなく
LinkedHashMap
が使用され、LinkedHashMapはHashMapから継承されます.これらの違いは、LinkedHashMapがHashMapの下部で配列を使用しているのは、上に2つの「ポインタ」がそれぞれ頭と尾を指していることです.add(E e)要素の追加
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
HashMapのputメソッドを直接呼び出し、要素eをmapのkey位置に配置して一意性を保証します.HashMapのputメソッドは,この位置に同じKey(==またはequals等しい)が既に存在する場合,元の古いvalueを新しいvalueで置き換え,古いvalueを返すことを知っているので,HashSetにとって最初の挿入はnullを返すことに成功し,後で同じ要素を再び挿入し,戻るのはオブジェクトであり,このような要素がすでに存在していることを示している.挿入に失敗しました.他のremoveではcontainsメソッドが似ています.
注意点
KeyIterator
を返します.public Iterator<E> iterator() {
return map.keySet().iterator();
}
この方法は反復時に配列がnullであるか否かをループ判定し,nullでない場合にはその位置に要素があると考える.したがって、初期容量を決定するには、HashSet反復のkeyをできるだけ小さく設定することが有利である.
まとめ
, !
関連記事:HashMapソースコードの全解析面接問題から:hashmap putメソッドjdk 1.8ソースコード解析-ARayList jdk 1.8 LinkedListソースコードの全分析スレッドプールを1行1行説明してください.面接?これを見れば十分だ.