【问题标题】:Stable element ordering issue while iterating HashMap in Java 8在 Java 8 中迭代 HashMap 时出现稳定的元素排序问题
【发布时间】:2016-09-10 16:22:36
【问题描述】:

某些测试用例在我的应用程序中失败,这取决于元素插入顺序。它曾经在 Java 7 中运行良好,但在升级到 Java 8 后开始出现此问题。在搜索互联网时,我在 article 中发现了这个问题:

Java 8 包含对 HashSet/Map 迭代顺序的一些可能更改:

请给我一些建议 - 考虑到我仍将在我的开发环境中使用 Java 1.8,我如何以与插入到 Map 中的顺序相同的顺序迭代 Map 中的对象?

是的,当然 HashMap 从来没有保证可以以相同的顺序检索对象,但是它曾经在 java 7 中工作过。

LinkedHashMap 是否可以实现这一点?

【问题讨论】:

  • LinkedHashMap 文档告诉你什么?
  • 您是否检查过 Java 7 HashMap 文档所说的内容?:docs.oracle.com/javase/7/docs/api/java/util/HashMap.html此类不保证地图的顺序;特别是,它不保证顺序会随着时间的推移保持不变。您必须使用其他保证顺序的集合 - LinkedHashMap
  • 使用 TreeMap 代替 javaDocs:基于红黑树的 NavigableMap 实现。地图根据其键的自然顺序进行排序,或者通过在地图创建时提供的 Comparator 进行排序,具体取决于使用的构造函数。
  • @RealSkeptic - 它告诉我们,它将按照条目放入地图的顺序进行迭代。我认为LinkedHahMap 会解决这个问题 - 但如果有人已经遇到这个问题并修复它,我仍然想确认它。
  • 确认它的正确方法是尝试它。与在机器上的确切情况下简单地尝试相比,询问人类这是否可行,效率要低得多。

标签: java hashmap java-8 linkedhashmap


【解决方案1】:

是的,您必须使用 LinkedHashMap,它具有稳定的迭代顺序,即使在 Java 版本之间也是如此,正如其 contract 所强制执行的那样:

此实现与 HashMap 的不同之处在于,它维护一个双向链表,贯穿其所有条目。这个链表定义了迭代顺序,通常是键插入映射的顺序(插入顺序)。请注意,如果将键重新插入到地图中,则插入顺序不会受到影响。

在某些情况下,我们还需要跨不同 Java 版本的可重复迭代顺序,而 LinkedHashMap 工作得很好。


TreeMap 也是稳定迭代顺序的解决方案。当然,它有一个对数运算时间(与LinkedHashMap 中的常数相反)并且迭代顺序不是插入顺序而是键顺序:

地图根据其键的自然顺序或通常在排序地图创建时提供的比较器进行排序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    • 2018-08-08
    相关资源
    最近更新 更多