HashMapの値を取得/取得できる順序を把握しようとしています。同じコードスニペットを示します。
import Java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
HashMap<Integer, String> hashmap = new HashMap<Integer, String>();
hashmap.put(1, "Apple" );
hashmap.put(2, "lemon" );
hashmap.put(3, "orange" );
hashmap.put(4, "banana" );
hashmap.put(5, "litchi" );
hashmap.put(6, "mango" );
hashmap.put(7, "papaya" );
System.out.println(hashmap.size());
for (String key : hashmap.values()) {
System.out.println(key);
}
}
}
7
Apple
lemon
orange
banana
litchi
mango
papaya
値は、挿入された順序で出力されます。これは一般的に本当ですか?値が任意の順序で出力されることを期待していました。これはJava 6。
値は、挿入された順序で出力されます。これは一般的に本当ですか?値がランダムな順序で出力されることを期待していました。
HashMap
APIは、反復の順序を定義しません。
ただし、HashMapの実装を見れば、反復順序、キーのハッシュ値、キーが挿入された順序、およびハッシュテーブルのサイズの間に複雑な一時的な関係があると推測できます。ハッシュテーブルのサイズが変更されると、この関係はスクランブルされます。
あなたの場合、Integer
キーを使用しています。つまり、キーのハッシュ値はキー値そのものです。また、キー順にエントリを挿入しました。これにより、(幸いなことに!)挿入順序と一致する反復順序になります。しかし、さらにキーを挿入し続けると、反復順序が「ラップアラウンド」することがわかります。その後、テーブルが一連のサイズ変更を経るにつれて、順序は次第にスクランブルされます。
要するに、あなたが見ているのはハッシュテーブル実装のアーティファクトであり、あなたが賢明に利用できる(またはすべきである)ものではありません。特に、それはcouldからJavaリリースへの変更。
Javadocから: HashMap
"クラスは、マップの順序について何の保証も行いません。特に、順序が時間とともに一定であることを保証しません。"
一貫した順序付けが必要な場合は、 LinkedHashMap
(挿入/アクセス順序の場合)または TreeMap
(比較順序の場合)を使用できます。これらは値ではなくキーの順序を維持することに注意してください。
LinkedHashMap はあなたが求めているものです。 docoからは、HashMapとは異なり、すべてのエントリを介して実行される二重リンクリストを維持します
順序が重要な場合は、LinkedHashMapを試してください... JavaDocから参照してください
パブリッククラスLinkedHashMapはHashMapを拡張します
Mapインターフェイスのハッシュテーブルとリンクリストの実装、予測可能な反復順序。この実装は、すべてのエントリを介して実行される二重リンクリストを維持するという点でHashMapと異なります。このリンクリストは、通常、キーがマップに挿入された順序(挿入順序)である反復順序を定義します。キーがマップに再挿入される場合、挿入順序は影響を受けないことに注意してください。 (m.containsKey(k)が呼び出しの直前にtrueを返すときにm.put(k、v)が呼び出されると、キーkはマップmに再挿入されます。)
関連するコレクションは、Java.util.concurrentの ConcurrentSkipListMap です。 skiplist を使用すると、エントリをキーの順序でトラバースし、ランダムな順序で検索することもできます(ただし、HashMapほど高速ではありません)。
ナイススキップリスト デモアプレット があります。