2017-01-17 5 views
9

コレクションからHashSetLinkedHashSetを作成すると、initialCapacityはデフォルトの実装では異なる値に設定されます。異なる初期値 'initialCapacity' HashSetとLinkedHashSet

HashSetの:

public HashSet(Collection<? extends E> c) { 
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); 
    addAll(c); 
} 

LinkedHashSetの:

public LinkedHashSet(Collection<? extends E> c) { 
    super(Math.max(2*c.size(), 11), .75f, true); 
    addAll(c); 
} 

私はこのために完全に正当な理由があると確信しているが、私はそれを見ることができません。ここにあなたが私たちを示したコードから

+0

ドキュメントをお読みください:初期容量と負荷係数: 'リンクハッシュセットは、その性能に影響を与える2つのパラメータがあります。それらはHashSetとまったく同じように定義されています。ただし、このクラスの反復時間は容量に影響されないため、初期クラスの容量を過度に高く設定する場合のペナルティは、このクラスではHashSetクラスよりも厳しくありません。 ' - https://docs.oracle.com/ javase/7/docs/api/java/util/LinkedHashSet.html –

+0

@TimBiegeleisen私はコメントでEnterを押すことができなかったことを知らなかった。 –

+0

Info: 'HashSet'はサイズまたは' 16'の '4/3'のうち大きい方を使いますが、' LinkedHashSet'は2倍の大きさ、つまり '11'を使います。両方とも、0.75fの負荷係数を使用します –

答えて

4

は、仕様がHashSetLinkedHashSetためのものです:として

data structure | initial capacity  | load factor 
HashSet  | max(1.333 * size, 16) | 0.75 
LinkedHashSet | max(2 * size, 11)  | 0.75 

私の頭の上オフ、プレーンなHashSetのよりLinkedHashSetのを焼き直ししおそらくよりコストがかかります前者にはリンクリストがあり、リファクタリング/再計算が必要な場合もあります。初期容量を大きくすることで、いくつかの典型的な使用事例の初期容量を超えないようにすることができます。

ハッシュテーブルのデータ構造の初期容量がJavaで超過する場合は、展開する必要があります。これには、とりわけ、テーブル内のすべてのエントリを新しいバケットに再ハッシュする必要があります。これを行うコストは、LinkedHashSetと平文HashSetの両方でほぼ同じでなければなりません。 ただし、の場合、LinkedHashSetには、エントリを実行するリンクリストが保持されているため、容量を拡張する際の追加要件があります。このリストはまた、プロセスでリファクタリングする必要があります。したがって、容量を増やすためのコストは、LinkedHashSetの方が平文よりも高くなると予想しています(HashSet)。 LinkedHashSetに大きな初期容量を与えることで、この高価な容量の拡張を、より長い時間にわたって避けることができます。あなたがここに質問を投稿する前に

LinkedHashSet Javadoc

+0

それは妥当と聞こえます。しかし、その前提が正しいとすれば、特にコレクションが非常に大きい場合、読み取り専用の目的でCollectionからLinkedHashSetを構築する際に、デフォルトに頼るべきではありません。 – marthursson

+0

"読み取り専用"の使用について覚えているユースケースで質問を更新できますか? –

+0

これは単なるメモではありませんか?私が実際にこれについて疑問を抱いていたことを考えると、読み取り専用の目的は有効な情報であることは明らかではありません:) – marthursson

関連する問題