web-dev-qa-db-ja.com

HashSetとLinkedHashSet

それらの違いは何ですか?そんなこと知ってる

LinkedHashSetは、すべての要素にわたって二重にリンクされたリストを維持するHashSetの順序付きバージョンです。反復順序を気にするときは、HashSetの代わりにこのクラスを使用します。 HashSetを反復処理する場合、順序は予測できませんが、LinkedHashSetを使用すると、要素が挿入された順序で要素を反復処理できます。

しかし、LinkedHashSetのソースコードには、HashSetの呼び出しコンストラクターのみがあります。では、二重リンクリストと挿入順序はどこにありますか?

143
Shikarn-O

答えはどのコンストラクター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);
}
62
aioobe

LinkedHashSetのコンストラクターは、次の基本クラスコンストラクターを呼び出します。

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
  map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);
}

ご覧のとおり、内部マップはLinkedHashMapです。 LinkedHashMapの中を見ると、次のフィールドが見つかります。

private transient Entry<K, V> header;

これが問題のリンクリストです。

25
NPE

HashSet isunorderedおよびunsortedSet。
LinkedHashSetは、HashSetの順序付きバージョンです。

HashSetLinkedHashSetの唯一の違いは次のとおりです。
LinkedHashSetは挿入順序を維持します。

HashSetを反復処理する場合、順序は予測不能ですが、LinkedHashSetの場合は予測可能です。

LinkedHashSetが挿入順序を維持する理由は次のとおりです。
基礎となる使用データ構造はDoubly-Linked-Listです。

12
Hema Ganapathy

呼び出すHashSetコンストラクターのソースを確認する必要があります。これは、単にMapではなく、バッキングLinkedHashMapHashMapにする特別なコンストラクターです。

9
ColinD

LinkedHashSetを使用することをお勧めします。これは、全体的なパフォーマンスの向上)があるためです。

  1. 予測可能反復順序 LinkedHashSet(Oracle)
  2. LinkedHashSetは、HashSetよりも挿入にコストがかかります。
  3. 一般的に反復処理にSet構造体を使用するため、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

ソーステストページは次のとおりです。 最終的なパフォーマンステストの例

5

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()

3
Justin

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
3
Phan Van Linh

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:

  1. 下線付きのデータ構造はHashtableです。
  2. 挿入順序は保持されません。
  3. 1.2バージョンを導入。

LinkedHashSet:

  1. 下線付きのデータ構造は、LinkedListとHashtableの組み合わせです。
  2. 挿入順序は保持されます。
  3. 1.4バージョンで導入されました。
2
Umapathi

LinkedHashSetクラスから呼び出されるコンストラクターを見ると、内部的にはLinkedHashMapがバッキングの目的で使用されていることがわかります。

1
reef

すべてのメソッドとコンストラクターは同じですが、LinkedHashsetは挿入順序を維持しますが、重複は許可されません。

ハッシュセットは挿入順序を維持しません。 ListとSet simpleの組み合わせです:)

0
Anand Mohan