LinkedHashMap
予測可能な反復順序(挿入順序)があることはわかっています。Set
返品者LinkedHashMap.keySet()
とCollection
返品者LinkedHashMap.values()
もこの順序を維持していますか?
7 に答える
Map インターフェースは 3 つの コレクション ビューを提供します。これにより、マップのコンテンツをキーのセット、値のコレクション、またはキーと値のマッピングのセットとして表示できます。マップの順序は、マップのコレクション ビューの反復子が要素を返す順序として定義されます。クラスなどの一部のマップ実装では
TreeMap
、順序に関して特定の保証が行われます。クラスのような他のものはHashMap
そうではありません。
--地図
この連結リストは反復順序を定義します。これは通常、キーがマップに挿入された順序 ( insert-order ) です。
したがって、はい、、、keySet()
およびvalues()
(entrySet()
前述の 3 つのコレクション ビュー) は、内部リンク リストが使用する順序で値を返します。そして、はい、それMap
をLinkedHashMap
保証する JavaDoc です。
結局のところ、それがこのクラスのポイントです。
ソースを見ると、そうであるように見えます。keySet()
、、values()
およびentrySet()
すべてが内部で同じエントリイテレータを使用します。
LinkedHashMap.keySet()
Setを返すことと混同しないLinkedHashMap.entrySet()
でください。したがって、順序を保証するものではありません。
Set
などとのインターフェースでありHashSet
、TreeSet
その実装です。インターフェイスのHashSet
実装は、Set
順序付けを保証しません。しかし、TreeSet
そうです。また、LinkedHashSet
そうです。
したがって、返される Set 参照が順序付けを保証するかどうかは、がどのようSet
に実装されているかに依存します。LinkedHashMap
のソースコードを確認LinkedHashMap
したところ、次のようになりました。
private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
Set
したがって、LinkedHashMap/HashMap にはieの独自の実装がありKeySet
ます。したがって、これを と混同しないでくださいHashSet
。
また、順序は要素がバケットに挿入される方法によって維持されます。の方法を見て、との主な違いを強調している のaddEntry(..)
方法LinkedHashMap
と比較してください。HashMap
HashMap
LinkedHashMap
そう推測できます。Javadoc には「予測可能な反復順序」と記載されており、Map で使用できる唯一の反復子は、 keySet()、entrySet()、および values() の反復子です。
したがって、それ以上の修飾がない場合は、それらのイテレータすべてに適用することを明確に意図しています。
AFAIKは文書化されていないため、「正式に」そのように想定することはできません。ただし、現在の実装が変更される可能性はほとんどありません。
順序を確認したい場合は、マップ全体を繰り返し処理し、選択した順序関数を使用して並べ替えられたセットに挿入することをお勧めします。ただし、当然、パフォーマンスコストは発生します。
Set
インターフェイスを見ると、ではなくプレーンが返されますSortedSet
。したがって、保証はありません。
実装(常に悪い考え)を見て暗黙の保証を想定する前に、他のすべてのJava実装の実装も見てください:)
たとえば、コンストラクターでkeySetを使用してTreeSetを作成することをお勧めします。
keySet() と values() の順序を推測できるとは思いません。
Map で定義され、HashMap でオーバーライドされるこれら 2 つのメソッドの規約に固執する限り、順不同の keySet() と values() を返す LinkedHashMap の実装を簡単に作成できます。