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


162

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


1
すべての回答がvalues()と同様にの問題を扱っているのでkeySet()、それを含めるように質問を拡張しました。これは、これの複製としてより多くの質問を閉じることができることを意味します。
Duncan Jones

回答:


226

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

- 地図

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

- のLinkedHashMap

だから、はい、keySet()values()、とentrySet()順番に内部リンクリストが使用する戻り値を(3つのコレクションビューは言及しました)。はい、JavaDocはMapそれをLinkedHashMap保証します。

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


8
マップの反復は、HashMapよりもLinkedHashMapを使用した方が高速に行われます。
ティエリー

2
values()はコレクションを返します。リストではありません。それをどのように整理するのですか?
Dejell

7
@Dejel Collectionは、values()が返すものの基本クラスです。返されるコレクションの実装は、引き続きによって制御されますLinkedHashMapLinkedHashMap場合、それは戻っていますLinkedValues、LinkedHashMap.java内部のプライベートクラスをインスタンスを。
Powerlord 2014

2
私の場合、LinkedHashMapのキーセットは、マップに表示されている順序ではありません。これには非常に戸惑います。
Amalgovinus

2
Mapマップのコレクションビューのイテレータにマップの順序を明示的に結び付ける(およびそれらのコレクションビューが何であるかを明確にする)ドキュメントにリンクしていただきありがとうございます。それは私にとって欠けていた作品でした。
LarsH 2016年

11

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


1
リポジトリへのリンクがあると便利ですが、私は怠惰です:-)もちろん、これは前方互換性を保証するものではありません。
Ciro Santilli郝海东冠状病六四事件法轮功

6

Setと混同しLinkedHashMap.keySet()LinkedHashMap.entrySet()返さないでください。したがって、順序付けは保証されません。

SetインターフェースであるHashSetTreeSetなどの生き物その実装。インターフェースの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


4
この回答は確かに有用な情報を提供しますが、実際には質問には答えません。基本的に、それらは予測可能な反復順序を持つことができると言っています。
Tuupertunut 16

5

あなたはそう仮定することができます。Javadocは「予測可能な繰り返し順序」と言って、地図で利用可能な唯一のイテレータはある()のkeySet()、のentrySet()、および値のもの。

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


0

AFAIKはドキュメント化されていないため、「正式に」想定することはできません。ただし、現在の実装が変更されることはほとんどありません。

順序を確実にしたい場合は、マップ全体を反復処理し、選択した順序関数を使用してソートセットに挿入することもできますが、当然、パフォーマンスコストが発生します。


entrySet()は順序を保証しますが、keySet()は保証しませんか?
user256239 2010年

1
@kknight:わかりません。javadocは次のように述べています。「このリンクリストは反復順序を定義しています。これは通常、キーがマップに挿入された順序(挿入順序)です。」ただし、JDKのJavaDocは一般的に非常にあいまいです。
ウリ

5
entrySet()でも反復順序が保証されない場合、LinkedHashMapとHashMapの違いは何ですか?LinkedHashMapインスタンスで予測可能な反復順序をどのように利用できますか?
user256239 2010年

1
最も確実文書化されています。答えは完全に間違っています。
ローンの侯爵

-3

インターフェイスを見ると、プレーンSetではなくプレーンが返されますSortedSet。したがって、保証はありません。

実装を見ることによって暗黙の保証を仮定する前に(常に悪い考え)、他のすべてのJava実装の実装も見てください:)

たとえば、コンストラクターでkeySetを使用してTreeSetを作成することをお勧めします。


3
ドキュメントを詳しく見ると、確かに保証があります。誰かがすでに書いたように、それがこのクラスのまさにポイントです。
glglgl 2016

-4

keySet()とvalues()の順序を推測できるとは思いません。

Mapで定義され、HashMapでオーバーライドされるこれら2つのメソッドの規約に固執する限り、順序なしのkeySet()とvalues()を返すLinkedHashMapの実装を簡単に作成できます。


6
LinkedHashMapクラスの目的は、マップを反復しながら要素の順序を維持することであり、この動作は十分に指定されています。基本クラスの仕様に準拠せずにサブクラスを作成すると、何かがおかしくなります。
zakinster 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.