【问题标题】:Why don't TreeMap.values() reflect the order in which elements were originally added?为什么 TreeMap.values() 不反映最初添加元素的顺序?
【发布时间】:2015-05-21 20:01:20
【问题描述】:

我需要一个data structure,它既可以按键执行lookup map 的角色,又可以转换为sorted list。输入的数据是一个非常简单的代码描述对(例如 M/MarriedD/Divorced 等)。查找要求是为了在用户在 UI 中进行选择后获取描述,其值为代码。排序列表要求是为了将数据提供给以List 作为输入的 UI 组件 (JSF),并且值始终需要以相同的顺序显示(描述的字母顺序)。

首先想到的是TreeMap。所以我按照我希望它在 UI 中显示的顺序从我的数据库中检索数据,并将其加载到我的树形图中,由代码键入,以便我以后可以在用户做出选择后查找描述以进一步显示。至于从同一张地图中获取排序列表,根据this post,我正在执行以下操作:

List<CodeObject> list = new ArrayList<CodeObject>(map.values());

但是,列表的排序顺序与它们放入地图的顺序不同。该地图被声明为 SortedMap 并实现为 TreeMap:

SortedMap<String, CodeObject> map = new TreeMap<String, CodeObject>().

CodeObject 是一个简单的POJO,只包含代码和描述以及相应的getter(通过构造函数传入的setter),其中的列表被提供给UI组件,UI组件使用代码作为值和描述来显示.我以前只使用一个 List 并且在排序方面工作得很好,但是 List 没有提供一个有效的接口来按键查找一个值,而我现在确实有这个要求。

所以,我的问题是:

  1. 如果 TreeMap 应该是按项目添加顺序排列的地图,为什么 TreeMap.values() 的顺序相同?
  2. 我应该怎么做才能满足上面解释的要求,即有一个既可以用作查找图又可以用作元素的排序集合的数据结构?如果我以不同的方式使用 TreeMap 或者我需要完全不同的方法,TreeMap 会为我做吗?

【问题讨论】:

  • 我认为您将TreeMapLinkedHashMap 混淆了。
  • TreeMaps 不是按插入顺序排列的。
  • 我总是被告知 TreeMap 保证它们被添加的条目的顺序
  • @amphibient:我的意思是TreeMap 保证的顺序不是添加/插入/您想要调用它的顺序。完全没有。 TreeMap键的自然顺序 排序——即compareTo 样式。所以说你的钥匙是字符串。排序将(很大程度上)按字母顺序排列。或者说它们是数字:排序将按数字。
  • @amphibient:我上面的原始评论(现已删除)的措辞真的很糟糕。对困惑感到抱歉。我的意思是它保证一个顺序,但它保证的顺序不是添加/插入的顺序。

标签: java sorting data-structures


【解决方案1】:

TreeMap 维护密钥的自然顺序。您甚至可以通过值的自然顺序/反向顺序对其进行排序(通过更多的操作和比较器的自定义定义)。但这与说“插入顺序”不同。要维护插入顺序,您需要使用 LinkedHashMap。 Java LinkedHashMapHashMap 的子类 - 类比与LinkedList 相同,您在其中维护下一个节点的跟踪。但是,它说它不能“保证”订单被维持,所以如果你突然看到一个广告订单被维持在HashMap

,请不要要求退款

【讨论】:

  • 实际上,您只能尝试使用“智能”黑客按价值排序,但这种尝试有时似乎有效。
  • 那个页面的相关性是什么?它显示了如何对LinkedList 进行排序。
【解决方案2】:

TreeMap 的文档说:

地图根据其键的自然顺序排序,或者根据地图创建时提供的Comparator 排序,具体取决于使用的构造函数。

因此,除非您提供 Comparator 并跟踪插入顺序并在该 Comparator 中使用它,否则您将获得键的自然顺序,而不是键的插入顺序。

如果你想要广告订单,as davide said,你可以使用LinkedHashMap

Map 接口的哈希表和链表实现,具有可预测的迭代顺序...这个链表定义了迭代顺序,通常是键插入映射的顺序(insertion-顺序)。请注意,如果将键重新插入到地图中,则插入顺序不会受到影响。

【讨论】:

    【解决方案3】:

    你需要的是LinkedHashMap 参见another question

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-18
      • 2020-07-07
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 2023-04-05
      • 2010-12-13
      相关资源
      最近更新 更多