13

私はこの非常に単純なコードを持っており、マップ内のさまざまな種類のオブジェクトで少し遊んでみました。

//There's a bit of spanish, sorry about that
//just think 'persona1' as an object with
//a string and an int
Map mapa = new HashMap();
mapa.put('c', 12850);
mapa.put(38.6, 386540);
mapa.put("Andrés", 238761);
mapa.put(14, "Valor de 14");
mapa.put("p1", persona1);
mapa.put("Andrea", 34500);

System.out.println(mapa.toString());

そして、私はコンソールから次のようなものを期待しています:

{c=12850, 38.6=386540, Andrés=238761, 14=Valor de 14, p1={nombre: Andres Perea, edad: 10}, Andrea=34500}

しかし、驚いたことに、同じデータを異なる順序で取得しました。

{38.6=386540, Andrés=238761, c=12850, p1={nombre: Andres Perea, edad: 10}, Andrea=34500, 14=Valor de 14}

文字列や数値型だけであっても、他の種類のオブジェクトを試しても問題ありません。常に同じことを行い、明らかに意味のない順序が異なります。

なぜこれが起こるのか、誰かが私にヒントを与えることができますか? それとも、私が見逃しているあまりにも明白なものでしょうか?

Java 1.7 と Eclipse Juno を使用しています。

4

5 に答える 5

21

オラクルのドキュメントによると

HashMap クラスは Hashtable とほぼ同等ですが、非同期で null を許可する点が異なります。このクラスは、マップの順序を保証しません。特に、順序が長期的に一定であることを保証するものではありません。

HashMap JavaDocsを参照してください。

于 2013-09-13T04:42:13.123 に答える
16

Java でマップ インターフェイスを実装するクラスは 3 つあります。1. hashMap: Id は順序を保証しません。2. リンクされた HashMap: 挿入順に格納されます。3. TreeMap : 昇順で格納されます。(ASCII値)

したがって、要件に応じて、書く代わりに HashMap.so の代わりに Linked HashMap を使用できます

Map mapa = new HashMap();

Linked HashMap のオブジェクトを作成

Map mapa = new LinkedHashMap();

詳細については、以下のリンクに従ってください。

http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html

于 2013-09-13T04:48:15.593 に答える
5

HashMapは要素の順序を保証しません。順序を維持したい場合は、LinkedHashMapを使用してください。

次のケースを参照してください

    Map<Integer,String> unOrderedMap=new HashMap<>();
    unOrderedMap.put(1,"a");
    unOrderedMap.put(3,"a");
    unOrderedMap.put(2,"a");
    System.out.println("HashMap output: "+unOrderedMap.toString());

    Map<Integer,String> orderedMap=new LinkedHashMap<>();
    orderedMap.put(1,"a");
    orderedMap.put(3,"a");
    orderedMap.put(2,"a");
    System.out.println("LinkedHashMap output: "+orderedMap.toString());

出力:

   HashMap output: {1=a, 2=a, 3=a}
   LinkedHashMap output: {1=a, 3=a, 2=a}
于 2013-09-13T04:44:21.857 に答える
1

Maps は要素が追加された順序を維持しません。List は要素の順序を維持します。

「マップの順序は、マップのコレクション ビューの反復子が要素を返す順序として定義されます。TreeMap クラスなどの一部のマップ実装では、順序に関して特定の保証が行われますが、HashMap クラスなどの他の実装では保証されません。 ."

于 2013-09-13T04:42:03.620 に答える
0

これがハッシュマップの仕組みです:(別のソースから引用)


キーと値のペアを格納するために使用する「バケット」がいくつかあります。各バケットには一意の番号があり、それがバケットを識別します。キーと値のペアをマップに入れると、ハッシュマップはキーのハッシュ コードを調べ、キーのハッシュ コードを識別子とするバケットにペアを格納します。例: キーのハッシュ コードは 235 -> ペアはバケット番号 235 に格納されます (1 つのバケットに複数のキーと値のペアを格納できることに注意してください)。

ハッシュマップでキーを指定して値を検索すると、指定したキーのハッシュ コードが最初に調べられます。次に、ハッシュマップは対応するバケットを調べ、指定したキーとバケット内のすべてのペアのキーを equals() で比較します。

これで、これがマップ内のキーと値のペアを検索するのに非常に効率的であることがわかります。キーのハッシュ コードによって、ハッシュマップは検索対象のバケットをすぐに認識できるため、そのバケットの内容に対してテストするだけで済みます。

上記のメカニズムを見ると、キーのhashCode()およびequals()メソッドに必要な要件もわかります。

  • 2 つのキーが同じ (比較すると equals() が true を返す) 場合、それらの hashCode() メソッドは同じ数値を返す必要があります。キーがこれに違反すると、等しいキーが異なるバケットに格納される可能性があり、ハッシュマップはキーと値のペアを見つけることができなくなります (同じバケットを検索するため)。

  • 2 つのキーが異なる場合、それらのハッシュ コードが同じかどうかは問題ではありません。ハッシュコードが同じ場合、それらは同じバケットに格納されます。この場合、ハッシュマップは equals() を使用してそれらを区別します。


ここで、すべての「キーと値」のペアをハッシュマップに入れて出力すると、キーに指定した値ハッシュすることによって生成されたキーのランダムな順序で出力されます。

それでも順序を維持する必要がある場合はLinkedHashMap、Java で を使用できます。

お役に立てれば :-)

編集: 元の投稿: Java HashMap は、同じハッシュ コードを持つ異なるオブジェクトをどのように処理しますか?

于 2013-09-13T04:49:00.830 に答える