web-dev-qa-db-ja.com

LinkedHashMapオブジェクトからキーと値が返される順序は保証されていますか?

LinkedHashMapには予測可能な反復順序(挿入順序)があることを知っています。 LinkedHashMap.keySet()によって返されるSetLinkedHashMap.values()によって返されるCollectionもこの順序を維持しますか?

143
user256239

Mapインターフェースは3つのcollectionビューを提供します。これにより、マップのコンテンツをキーのセット、値のコレクション、またはキーと値のセットとして表示できます。マッピング。マップのorderは、マップのコレクションビューの反復子が要素を返す順序として定義されます。 TreeMapクラスなどの一部のマップ実装は、順序について特定の保証を行います。 HashMapクラスのような他のものはそうしません。

- マップ

このリンクリストは反復順序を定義します。これは通常、キーがマップに挿入された順序です(insertion-order)。

- LinkedHashMap

そのため、はい、keySet()values()、およびentrySet()(上記の3つのコレクションビュー)は、内部リンクリストが使用する順序で値を返します。そして、はい、MapLinkedHashMapのJavaDocはそれを保証します。

結局のところ、それがこのクラスのポイントです。

207
Powerlord

ソースを見ると、そのように見えます。 keySet()values()、およびentrySet()はすべて、内部で同じエントリイテレータを使用します。

11
sblundy

LinkedHashMap.keySet()およびLinkedHashMap.entrySet()がSetを返すことと混同しないでください。したがって、順序を保証するべきではありません!

Setは、その実装であるHashSetTreeSetなどとのインターフェースです。 HashSetインターフェイスのSet実装は、順序付けを保証しません。しかし、TreeSetはそうです。 LinkedHashSetも同様です。

したがって、SetLinkedHashMapにどのように実装されているかによって、返されるSet参照が順序付けを保証するかどうかを知ることができます。 LinkedHashMapのソースコードを調べたところ、次のようになっています。

_private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
_

したがって、LinkedHashMap/HashMapには、Setの独自の実装、つまりKeySetがあります。したがって、これをHashSetと混同しないでください。

また、順序は、要素がバケットに挿入される方法によって維持されます。 LinkedHashMapaddEntry(..)メソッドを見て、HashMapHashMapの主な違いを強調するLinkedHashMapのメソッドと比較します。

7
anzaan

あなたはそう仮定できます。 Javadocには「予測可能な反復順序」と書かれており、Mapで利用可能な唯一の反復子are keySet()、entrySet()、values()の反復子です。

したがって、それ以上の資格がない場合は、これらの反復子すべてに適用することが明確に意図されています。

5
user207421

知る限り、それは文書化されていないので、「正式に」そう仮定することはできません。ただし、現在の実装が変更されることはほとんどありません。

順序を確保したい場合は、当然のことながらパフォーマンスコストを支払うことになりますが、マップ全体を反復処理し、選択した順序関数でソートされたセットに挿入することができます。

0
Uri