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にはSetieの独自の実装がありKeySetます。したがって、これをと混同しないでくださいHashSet。
また、順序は、要素がバケットに挿入される方法によって維持されます。見てaddEntry(..)の方法LinkedHashMapとのそれと比較HashMapの主な違いは強調しているHashMapとしますLinkedHashMap。
AFAIKはドキュメント化されていないため、「正式に」想定することはできません。ただし、現在の実装が変更されることはほとんどありません。
順序を確実にしたい場合は、マップ全体を反復処理し、選択した順序関数を使用してソートセットに挿入することもできますが、当然、パフォーマンスコストが発生します。
インターフェイスを見ると、プレーンSetではなくプレーンが返されますSortedSet。したがって、保証はありません。
実装を見ることによって暗黙の保証を仮定する前に(常に悪い考え)、他のすべてのJava実装の実装も見てください:)
たとえば、コンストラクターでkeySetを使用してTreeSetを作成することをお勧めします。
keySet()とvalues()の順序を推測できるとは思いません。
Mapで定義され、HashMapでオーバーライドされるこれら2つのメソッドの規約に固執する限り、順序なしのkeySet()とvalues()を返すLinkedHashMapの実装を簡単に作成できます。
LinkedHashMapクラスの目的は、マップを反復しながら要素の順序を維持することであり、この動作は十分に指定されています。基本クラスの仕様に準拠せずにサブクラスを作成すると、何かがおかしくなります。
values()と同様にの問題を扱っているのでkeySet()、それを含めるように質問を拡張しました。これは、これの複製としてより多くの質問を閉じることができることを意味します。