【问题标题】:Why HashMap does not guarantee that the order of the map will remain constant over time为什么 HashMap 不保证地图的顺序会随着时间的推移保持不变
【发布时间】:2013-02-04 13:05:53
【问题描述】:

我在这里阅读了 Hashmap 和 Hashtable 之间的区别: http://javarevisited.blogspot.sg/2010/10/difference-between-hashmap-and.html

谁能解释一下为什么它说跟随?

“5. HashMap 不保证地图的顺序会随着时间的推移保持不变。”

在重新散列过程中顺序是否会改变,这是为什么?

如果您能指出资源或集合列表,这些资源或集合列表表现出不保证订单保持不变的行为,那也很好。

AFIK,ArrayList 提供这样的保证(如果我错了,请告诉我)

编辑:“地图顺序”= 可能是输入键或值的顺序。

【问题讨论】:

  • 如果您想保留键的插入顺序,请使用 LinkedHashMap
  • 我不确定这篇文章是否正确。我在 javadoc 中看不到任何保证 Hashtable 将保留顺序,只是没有明确提到它不会(而 HashMap 的 javadoc 是明确的)。
  • 你能定义“地图的顺序”吗?恕我直言,当这样的东西根本不存在时说它不被保存有点错误。
  • @Ingo:所有映射(和集合)都具有由其迭代器定义的隐式顺序。对于Map,它是entrySet().iterator(),定义了它的顺序
  • @LukasEder 迭代器确实会以某种顺序返回元素 - 但这并不意味着它从中获取元素的东西定义(或具有)任何顺序。考虑一个 Iterator,其中 next() 是 Random.nextDouble()。

标签: java hashmap


【解决方案1】:

HashMap 没有订单 - 任何时候。它实际上不用于此目的。即使不重新散列,顺序可能也会改变。

如果您需要订单保持不变,请使用LinkedHashMap

【讨论】:

  • 尝试将 0 到 10 添加到 HashSet 中,它将按排序顺序排列。 :0
  • 该声明的任何证据,@PeterLawrey,还是只是经验“证据”?
  • 他是对的,但这只是因为实施。没有什么能保证它总是正确的。
  • 感谢您的信息。在接受这个作为答案之前,我将等待一些更有用的 cmets/answer。
  • @Ingo,证明在代码中。整数的 hashCode 只返回导致每个数字在 0 到 10 桶中的值,但正如 Vakimshaar 指出的那样,不能保证这一点。
【解决方案2】:

散列策略的要点是以伪随机方式放置对象。这样做是为了在大多数情况下,只有一个键/元素会被散列到给定的存储桶中。这允许 O(1) 查找时间。当 HashMap 或 Hashtable 增长时,桶的数量会发生变化,并且键/元素以另一种伪随机方式放置。

最简单的解决方案是使用 LinkedHashMap。这将保持添加顺序或可选的最后访问顺序。我更喜欢使用这个集合,因为它使调试更容易,因为我可以预测对象可能在哪里,而且有时添加对象的顺序可能是有用的信息。

顺便说一句,如果您对少量密钥可以有多少订单感兴趣Order of elements in a hash collection

【讨论】:

    【解决方案3】:

    以下代码对我来说:

    Map <Integer, Object> map = new HashMap <Integer, Object> (4);
    
    map.put (60, null);
    map.put (48, null);
    map.put (29, null);
    
    System.out.println (map);
    
    map.put (47, null);
    map.put (15, null);
    map.put (53, null);
    
    map.remove (47);
    map.remove (15);
    map.remove (53);
    
    System.out.println (map);
    

    输出:

    {29=null, 48=null, 60=null}
    {48=null, 29=null, 60=null}
    

    由于超出初始容量(此处为 4)时发生的重新散列而更改了顺序。即使再次删除了额外的条目,原始顺序也不会恢复。

    【讨论】:

    • 嗯,这不是一个真正的答案。这只是使用HashMap发生了什么 的一个相当随意的示例,而不是为什么 它会发生
    • 在调试器中单步执行这个例子会告诉你原因。地图容量为 4,当添加另外三个元素并更改前三个元素的顺序时发生重新散列。删除最新的三个元素后,原始顺序未恢复。
    • 呵呵 :-) 我明白了。请注意,Stack Overflow 上的一个好的答案直接在答案中包含此类 cmets。如果您在回答中添加关于为什么会发生这种情况的解释(例如内联 cmets、一些文本等),我会投票赞成。
    【解决方案4】:

    一个 HashMap 有许多桶(实现为一个数组)来存储条目。

    当一个项目被添加到地图时,它被分配到一个基于其 hashCode 的值和 HashMap 的桶大小的桶。 (请注意,桶可能已被占用,这称为冲突。处理得当且正确,但我将忽略该处理的描述,因为它不会改变概念)。

    Why HashMap does not guarantee that the order of the map will remain constant over time

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-02
      • 1970-01-01
      • 2014-02-04
      • 2014-02-05
      • 2015-11-16
      • 1970-01-01
      相关资源
      最近更新 更多