LinkedHashMap
予測可能な反復順序(挿入順序)があることはわかっています。んSet
で返されるLinkedHashMap.keySet()
と、Collection
によって返さLinkedHashMap.values()
も、この順序を維持しますか?
LinkedHashMap
予測可能な反復順序(挿入順序)があることはわかっています。んSet
で返されるLinkedHashMap.keySet()
と、Collection
によって返さLinkedHashMap.values()
も、この順序を維持しますか?
回答:
Mapインターフェースは3つのコレクションビューを提供し ます。これにより、マップのコンテンツをキーのセット、値のコレクション、またはキーと値のマッピングのセットとして表示できます。マップの順序は、マップのコレクションビューのイテレータが要素を返す順序として定義されます。
TreeMap
クラスのような一部のマップ実装は、その順序に関して特定の保証を行います。HashMap
クラスのような他の人は しません。
- 地図
このリンクされたリストは、反復順序を定義します。これは、通常、キーがマップに挿入された順序です(挿入順序)。
だから、はい、keySet()
、values()
、とentrySet()
順番に内部リンクリストが使用する戻り値を(3つのコレクションビューは言及しました)。はい、JavaDocはMap
それをLinkedHashMap
保証します。
結局、それがこのクラスのポイントです。
Collection
は、values()が返すものの基本クラスです。返されるコレクションの実装は、引き続きによって制御されますLinkedHashMap
。LinkedHashMap
場合、それは戻っていますLinkedValues
、LinkedHashMap.java内部のプライベートクラスをインスタンスを。
Map
マップのコレクションビューのイテレータにマップの順序を明示的に結び付ける(およびそれらのコレクションビューが何であるかを明確にする)ドキュメントにリンクしていただきありがとうございます。それは私にとって欠けていた作品でした。
ソースを見ると、そのように見えます。keySet()
、values()
、およびentrySet()
すべての内部で同じエントリのイテレータを使用しています。
Setと混同しLinkedHashMap.keySet()
て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> {...}
したがって、LinkedHashMap / HashMapにはSet
ieの独自の実装がありKeySet
ます。したがって、これをと混同しないでくださいHashSet
。
また、順序は、要素がバケットに挿入される方法によって維持されます。見てaddEntry(..)
の方法LinkedHashMap
とのそれと比較HashMap
の主な違いは強調しているHashMap
としますLinkedHashMap
。
AFAIKはドキュメント化されていないため、「正式に」想定することはできません。ただし、現在の実装が変更されることはほとんどありません。
順序を確実にしたい場合は、マップ全体を反復処理し、選択した順序関数を使用してソートセットに挿入することもできますが、当然、パフォーマンスコストが発生します。
インターフェイスを見ると、プレーンSet
ではなくプレーンが返されますSortedSet
。したがって、保証はありません。
実装を見ることによって暗黙の保証を仮定する前に(常に悪い考え)、他のすべてのJava実装の実装も見てください:)
たとえば、コンストラクターでkeySetを使用してTreeSetを作成することをお勧めします。
keySet()とvalues()の順序を推測できるとは思いません。
Mapで定義され、HashMapでオーバーライドされるこれら2つのメソッドの規約に固執する限り、順序なしのkeySet()とvalues()を返すLinkedHashMapの実装を簡単に作成できます。
LinkedHashMap
クラスの目的は、マップを反復しながら要素の順序を維持することであり、この動作は十分に指定されています。基本クラスの仕様に準拠せずにサブクラスを作成すると、何かがおかしくなります。
values()
と同様にの問題を扱っているのでkeySet()
、それを含めるように質問を拡張しました。これは、これの複製としてより多くの質問を閉じることができることを意味します。