それらの違いは何ですか?そんなこと知ってる
LinkedHashSetは、すべての要素にわたって二重にリンクされたリストを維持するHashSetの順序付きバージョンです。反復順序を気にするときは、HashSetの代わりにこのクラスを使用します。 HashSetを反復処理する場合、順序は予測できませんが、LinkedHashSetを使用すると、要素が挿入された順序で要素を反復処理できます。
しかし、LinkedHashSetのソースコードには、HashSetの呼び出しコンストラクターのみがあります。では、二重リンクリストと挿入順序はどこにありますか?
答えはどのコンストラクターLinkedHashSet
が基本クラスの構築に使用するかです。
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true); // <-- boolean dummy argument
}
...
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true); // <-- boolean dummy argument
}
...
public LinkedHashSet() {
super(16, .75f, true); // <-- boolean dummy argument
}
...
public LinkedHashSet(Collection<? extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true); // <-- boolean dummy argument
addAll(c);
}
そして、ブール引数を取るHashSet
コンストラクター(の1つの例)が記述され、次のようになります。
/**
* Constructs a new, empty linked hash set. (This package private
* constructor is only used by LinkedHashSet.) The backing
* HashMap instance is a LinkedHashMap with the specified initial
* capacity and the specified load factor.
*
* @param initialCapacity the initial capacity of the hash map
* @param loadFactor the load factor of the hash map
* @param dummy ignored (distinguishes this
* constructor from other int, float constructor.)
* @throws IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}
LinkedHashSet
のコンストラクターは、次の基本クラスコンストラクターを呼び出します。
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);
}
ご覧のとおり、内部マップはLinkedHashMap
です。 LinkedHashMap
の中を見ると、次のフィールドが見つかります。
private transient Entry<K, V> header;
これが問題のリンクリストです。
HashSet isunorderedおよびunsortedSet。
LinkedHashSetは、HashSetの順序付きバージョンです。
HashSetとLinkedHashSetの唯一の違いは次のとおりです。
LinkedHashSetは挿入順序を維持します。
HashSetを反復処理する場合、順序は予測不能ですが、LinkedHashSetの場合は予測可能です。
LinkedHashSetが挿入順序を維持する理由は次のとおりです。
基礎となる使用データ構造はDoubly-Linked-Listです。
呼び出すHashSet
コンストラクターのソースを確認する必要があります。これは、単にMap
ではなく、バッキングLinkedHashMap
をHashMap
にする特別なコンストラクターです。
LinkedHashSet
を使用することをお勧めします。これは、全体的なパフォーマンスの向上)があるためです。
HashMap
よりもパフォーマンスが若干向上します。パフォーマンステスト:
------------- TreeSet -------------
size add contains iterate
10 746 173 89
100 501 264 68
1000 714 410 69
10000 1975 552 69
------------- HashSet -------------
size add contains iterate
10 308 91 94
100 178 75 73
1000 216 110 72
10000 711 215 100
---------- LinkedHashSet ----------
size add contains iterate
10 350 65 83
100 270 74 55
1000 303 111 54
10000 1615 256 58
ソーステストページは次のとおりです。 最終的なパフォーマンステストの例
HashSet:実際には順序付けられていません。パラメータを渡すと
Set<Integer> set=new HashSet<Integer>();
for(int i=0;i<set.length;i++)
{
SOP(set)`enter code here`
}
出力:2,1,3
は予測不能である可能性があります。次回別の注文。
FIFOオーダーを生成するLinkedHashSet()
。
HashSet
維持しない挿入アイテムの順序LinkedHashSet
維持挿入アイテムの順序
例
Set<String> set = ...;// using new HashSet<>() OR new LinkedHashSet<>()
set.add("2");
set.add("1");
set.add("ab");
for(String value : set){
System.out.println(value);
}
HashSet
の出力
1
ab
2
LinkedHashSet
の出力
2
1
ab
HashSet:
下線付きのデータ構造はHashtableです。重複オブジェクトは許可されません。挿入順序は保持されず、オブジェクトのハッシュコードに基づいています。ヌル挿入が可能です(1回のみ)。 Serializable、Clonableを実装しますが、RandomAccessインターフェースは実装しません。 HashSetは、頻繁な操作が検索操作である場合に最適です。
HashSetでは、重複は許可されていません。コンパイルまたはランタイムの例外が発生しない場合にユーザーが重複を挿入しようとしている場合。 addメソッドは単にfalseを返します。
コンストラクタ:
HashSet h = new HashSet();デフォルトの初期容量16で空のHashSetオブジェクトを作成し、デフォルトの充填率(負荷係数)は0.75です。
HashSet h = new HashSet(int initialCapacity);指定されたinitialCapacityで空のHashSetオブジェクトを作成します。デフォルトの充填率は0.75です。
HashSet h = new HashSet(int initialCapacity、float fillRatio);
HashSet h = new HashSet(Collection c);指定されたコレクションに相当するHashSetオブジェクトを作成します。このコンストラクタは、コレクションオブジェクト間の相互変換を目的としています。
LinkedHashSet:
HashSetの子クラスです。次の違いを除いて、(コンストラクタとメソッド)を含むHashSetとまったく同じです。
違いHashSet:
LinkedHashSet:
LinkedHashSet
クラスから呼び出されるコンストラクターを見ると、内部的にはLinkedHashMap
がバッキングの目的で使用されていることがわかります。
すべてのメソッドとコンストラクターは同じですが、LinkedHashsetは挿入順序を維持しますが、重複は許可されません。
ハッシュセットは挿入順序を維持しません。 ListとSet simpleの組み合わせです:)