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

2022-08-31 14:38:43

我正在尝试找出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。


答案 1

来自Javadoc:HashMap“类对映射的顺序不做任何保证;特别是,它并不能保证订单会随着时间的推移而保持不变。

如果需要一致的排序,可以使用LinkedHashMap(用于插入/访问顺序)或TreeMap(用于比较顺序)。请注意,它们维护的是键的顺序,而不是值的顺序。


答案 2

这些值将按其插入的顺序打印。一般来说,这是真的吗?我期望以随机顺序打印这些值。

API 不定义迭代的顺序。HashMap

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

在您的例子中,您使用的是键,这意味着键的哈希值是键值本身。此外,您还按键顺序插入了条目。这导致(偶然!)迭代顺序与插入顺序匹配。但是,如果您不断插入更多键,您会发现迭代顺序“环绕”了。然后,随着表进行一系列调整大小调整,订单将逐渐变得越来越混乱。Integer

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