HashMap插入顺序

时间:2016-02-23 20:28:06

标签: java collections hashmap

当知道HashMap以无序方式存储和检索元素时,为什么HashMap以有序的方式检索

HashMap m = new HashMap();
m.put("A", 1);
m.put("B", 2);
m.put("C", 3);
m.put("D", 4);
m.put("E", 5);

Set keySet = m.keySet();
Iterator it = keySet.iterator();
while(it.hasNext())
{
    System.out.println(m.get(it.next()));
}

输出 - 1 2 3 4 5

3 个答案:

答案 0 :(得分:3)

简而言之:你很幸运。 HashMap通常以任意无意义的顺序返回元素,而这种情况恰好是所有元素按顺序出现的。

答案 1 :(得分:3)

在这种特殊情况下,A B C D E的hashCodes越来越多地被命令。

 while(it.hasNext())
 {
    String next = it.next();
    System.out.println(next.hashCode() + " "+ m.get(next));
 }

将产生以下

65 1
66 2
67 3
68 4
69 5

然而,这并不意味着每次你有一组越来越有序的哈希码时,map-entries将被存储在他们的hashCodes中。订购。

答案 2 :(得分:0)

由于两件事:

这是hashCode()的{​​{1}}实现:

String

对于单字符字符串,它只是该字符的Unicode值。这些字母(A-E)具有连续值(65-69)。

HashMap class modifies the hash a little bit,但在这种情况下具有如此低的值,该值不受影响。

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

HashMap will reduce the hash code modulo the number of buckets查找密钥的桶号。在这种情况下,存储桶编号都是顺序的 - static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } 1234。因此,迭代器按顺序遍历存储桶。

如果发生任何这些事情,其中​​一些不在5合同中且不在您的控制范围内,则迭代顺序可能会发生变化。

  • 添加不具有相同商模16的其他密钥,例如“Z”,“a”,“AA”。
  • 创建一个默认容量较小的地图。
  • Java决定混淆HashMap内部的hash方法。
  • Java决定混淆将哈希码映射到HashMap内部的桶号的算法。
  • Java决定混淆HashMap中的hashCode方法。