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

问题描述 投票:0回答:6

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

java hashmap
6个回答
94
投票

来自 Javadoc:

HashMap
“类不保证映射的顺序;特别是,它不保证顺序随着时间的推移保持不变。”

如果需要一致的排序,可以使用

LinkedHashMap
(用于插入/访问顺序)或
TreeMap
(用于比较顺序)。请注意,这些保持键的顺序,而不是值的顺序。


83
投票

这些值按照插入的顺序打印。总体来说这是真的吗?我期望这些值以随机顺序打印。

HashMap
API 未定义迭代顺序。

但是,如果你看一下 HashMap 的实现,你可以推断出迭代顺序、键的哈希值、键插入的顺序和哈希表的大小之间存在复杂的瞬态关系。如果哈希表自行调整大小,这种关系就会变得混乱1

在您的情况下,您使用的是

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

简而言之,您所看到的是哈希表实现和特定

hashCode
方法的产物。它不是您可以(或应该)明智地利用的东西。尤其是因为它可以从一个 Java 版本更改为下一个版本(并且已经更改)!


1 - 或者在 Java 8 或更高版本中,如果特定哈希桶/哈希链的拥塞导致其从简单列表切换到红黑树。深入的实施细节。如果您好奇,请阅读源代码!


11
投票

A LinkedHashMap 就是您所追求的。从 doco 来看,它与 HashMap 不同,因为它维护一个贯穿其所有条目的双向链表


7
投票

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

公共类 LinkedHashMap 扩展 哈希映射

哈希表和链表 地图接口的实现, 具有可预测的迭代顺序。这 实现与 HashMap 的不同之处在于 它维护一个双向链表 遍历其所有条目。 这个链表定义了迭代 ordering,通常是顺序 其中钥匙被插入到 地图(插入顺序)。注意 插入顺序不受影响,如果 密钥被重新插入到地图中。 (A 密钥 k 被重新插入到映射 m 中,如果 m.put(k, v) 被调用时 m.containsKey(k) 将返回 true 就在调用之前。)


1
投票

相关的集合是 java.util.concurrent 的 ConcurrentSkipListMapskiplist 允许您按键顺序遍历条目,也可以按随机顺序查看它们(但不如 HashMap 快)。

有一个不错的跳过列表演示小程序


-1
投票

不,在 HashMap 中不会保留顺序(如果您想要排序实现。) 如果您希望对键进行排序,可以使用 TreeMap。

例如- {[3=1],[2=50],[20=4],[14=1]} -> HashMap

对于 TreeMap,你得到 - {[2=50],[3=1],[14=1],[20=4]} -> TreeMap

© www.soinside.com 2019 - 2024. All rights reserved.