从HashMap检索的值的顺序是插入顺序

jav*_*url 58 java hashmap

我正在尝试找出可以检索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);
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

输出:

7
apple
lemon
orange
banana
litchi
mango
papaya
Run Code Online (Sandbox Code Playgroud)

值按插入顺序打印.一般来说这是真的吗?我期待值以任意顺序打印.这是使用Java 6.

not*_*oop 83

来自Javadoc:HashMap"类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变."

如果您需要一致的订购,您可以使用LinkedHashMap(用于插入/访问订单)或TreeMap(用于比较订单).请注意,这些维护键的顺序,而不是值.

  • 我认为OP正在问为什么HashMap*出现*以保留其用例中的插入顺序.很明显,他期望*迭代顺序更随机. (2认同)

Ste*_*n C 71

值按插入顺序打印.一般来说这是真的吗?我期待值以随机顺序打印.

HashMapAPI没有定义迭代的顺序.

但是,如果查看HashMap的实现,可以推断迭代顺序,键的哈希值,键的插入顺序和哈希表的大小之间存在复杂的瞬态关系.如果哈希表调整自身大小,则此关系会被扰乱.

在您的情况下,您使用的是Integer密钥,这意味着密钥的哈希值本身就是密钥值.此外,您按键顺序插入条目.这导致(偶然!)到与插入顺序匹配的迭代顺序.但是如果你继续插入更多的键,你会发现迭代顺序"包裹".然后,随着表格经历一系列调整,订单将逐渐变得越来越混乱.

简而言之,您所看到的是哈希表实现的人工制品,而不是您可以(或应该)明智地使用的东西.尤其是因为它可以从一个Java版本更改为下一个版本.


Rog*_*Rog 10

一个LinkedHashMap的是你追求的.从doco中,它与HashMap的不同之处在于它维护着一个贯穿其所有条目的双向链表


Mad*_*urf 5

如果顺序很重要,请尝试LinkedHashMap ...请参阅JavaDoc

公共类LinkedHashMap扩展了HashMap

Map接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与HashMap的不同之处在于,它维护贯穿其所有条目的双向链接列表。此链表定义了迭代顺序,通常是将键插入映射的顺序(插入顺序)。请注意,如果将密钥重新插入到映射中,则插入顺序不会受到影响。(如果在调用之前m.containsKey(k)即将返回true时调用了m.put(k,v),则将密钥k重新插入到映射m中。)