【问题标题】:Re-order Map based on ordering of List根据 List 的排序重新排序 Map
【发布时间】:2019-03-29 10:06:33
【问题描述】:

假设我有两个数据结构,一个有序的字符串列表和一个 HashMap。列表如下所示:

types = ["string", "integer", "boolean", "integer"];

还有一个带有对象键和字符串值的 HashMap,如下所示:

map = {2=integer, true=boolean, 7=integer, "dog"=string};

什么是重新组织地图“顺序”的最简单/最有效的方法,以便地图的值与列表的顺序一致,即地图现在在打印时看起来像这样:

map = {"dog"=string, 2=integer, true=boolean, 7=integer};

【问题讨论】:

  • 这看起来很痛苦,而且可能至少需要一张额外的地图...
  • types 列表的大小是否总是与预期的排序映射相同?
  • @FedericoPeraltaSchaffner 是的;每个都必须是相同的大小。
  • 好! @mettleap 有 the right answer,那么。

标签: java list sorting hashmap


【解决方案1】:

HashMap 不提供订单保证。来自documentation

这个类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

因此,如果您想要一个有序的 Map,您通常希望从实现 SortedMap (documentation) 开始。

不幸的是,SortedMap 按键排序,而您希望按值排序,因此您要么必须查看第三方集合库,要么考虑使用类似 LinkedHashMap (documentation) 的东西,这具有可预测的迭代顺序,即使它不维护排序。

如您的示例所示,当有两个整数时,您将使用什么策略来决定使用哪个整数?

【讨论】:

  • 从原始hashmap中获取所有键值对,按值排序,然后放入LinkedhashMap或SortedMap中
  • 请注意,示例中有两个integer值在排序中,一个在中间,一个在末尾——哪个整数应该是哪个?
  • @FedericoPeraltaSchaffner,我写了一个答案。您可以构建一个反向地图,然后继续
  • @GeoffreyWiseman,如果是两个整数,顺序无关紧要。
  • 我把两个整数扔进去只是为了有多个相同类型的值——我可以很容易地添加第二个字符串或布尔值。但就我所问的而言,相同类型的顺序并不特别重要——在重新排序中,7 很容易排在 2 之前——只要将每个都放入一个整数“槽”中。
【解决方案2】:

像这样构建一个反向哈希图,

types = ["string", "integer", "boolean", "integer"];

map = {2=integer, true=boolean, 7=integer, "dog"=string};

reversedmap = {integer=[2,7], boolean=true, string=dog};

然后遍历列表并从 reversedmap 中获取相应的键。

例如,首先你从类型中得到“字符串” -> 所以你知道对应的键应该是“狗”。将此键值对插入到其他某个映射(LinkedHashMap 类型)中。继续这样做,直到到达类型列表的末尾。

编辑:感谢@FedericoPeraltaSchaffner 指出这一点。

如果您从 reversedmap 中获得两个值(例如,在“整数”元素的情况下),您可以选择其中一个(不管是哪个)插入到 LinkedHashMap 中,同时随后将其从反转地图。然后你进入类型列表中的下一个元素

【讨论】:

  • @FedericoPeraltaSchaffner,谢谢 :)。但我不明白你对最后一部分的建议。能详细点吗?
  • 对不起,我很困惑,每个列表中元素的顺序无关紧要。但是一旦你把一个元素放到地图中,你就需要从列表中删除它,所以下次有相同类型的元素要放入地图时,你只需从列表中选择另一个。
  • @FedericoPeraltaSchaffner,哦。实际上,但我认为即使这样也不是必需的。从 reversedmap 中获取多个值后,请仅在将所有可能的键值对插入 LinkedHashMap 后继续
  • 不,您必须尊重types 列表的遇到顺序。对于问题中的示例,您首先在types列表中找到(string, [dog]),然后转到反向映射并将(dog, string)放入LinkedHashMap中,并将dog从值列表中删除反向地图。 types 列表中的下一个元素是integer,您可以在反向映射中找到(integer, [2, 7])。在这里,您应该选择27删除它。假设您选择并删除了2,那么将(2, integer) 放入LinkedHashMap。然后继续使用boolean,然后再次使用integer...
  • @FedericoPeraltaSchaffner,哦……现在明白了 :)……谢谢!
猜你喜欢
  • 2015-02-14
  • 2021-03-26
  • 2014-02-05
  • 2016-11-25
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多