【问题标题】:nth item of hashmaphashmap的第n项
【发布时间】:2011-02-09 01:31:22
【问题描述】:
HashMap selections = new HashMap<Integer, Float>();

如何获取所有 HashMap 中 Float 的第 3 个较小值的 Integer 键?

编辑 我为此使用HashMap

for (InflatedRunner runner : prices.getRunners()) {
       for (InflatedMarketPrices.InflatedPrice price : runner.getLayPrices()) {
           if (price.getDepth() == 1) {
             selections.put(new Integer(runner.getSelectionId()), new Float(price.getPrice()));
           }
         }                    

}

我需要深度为 1 的第三个较小价格的跑步者

也许我应该以另一种方式实现它?

【问题讨论】:

  • 如果您告诉我们更多关于selections 是什么以及您如何使用此查询的信息,我们或许可以为您推荐更好的数据结构。
  • 每个跑步者可以有多个深度为 1 的价格吗?因为如果可能的话,那么您现在的selections 将只为每个runner 保留其中一个。
  • 不,只有 3 个深度.. 1、2 和 3
  • 但是跑步者的getLayPrices 在深度 1 处返回超过 1 个价格吗?
  • 不不,只是且始终各有 1 个

标签: java algorithm hashmap


【解决方案1】:

如果您使用的是HashMap,Michael Mrozek 用他的问题指出了这一点:这对于HashMap 来说是非常不典型的情况。也就是说,您可以执行以下操作:

  • HashMap&lt;K,V&gt;.entrySet() 获取Set&lt;Map.Entry&lt;K,V&gt;&gt;
  • addAllList&lt;Map.Entry&lt;K,V&gt;&gt;
  • Collections.sort 具有自定义 Comparator&lt;Map.Entry&lt;K,V&gt;&gt; 的列表,该列表基于 V 进行排序。
    • 如果您只需要第三个Map.Entry&lt;K,V&gt;,那么O(N) selection algorithm 就足够了。

//修改后

看起来selection 应该真的是SortedMap&lt;Float, InflatedRunner&gt;。你应该看看java.util.TreeMap

这是一个如何使用TreeMap 获取第三低键的示例:

TreeMap<Integer,String> map = new TreeMap<Integer,String>();
map.put(33, "Three");
map.put(44, "Four");
map.put(11, "One");
map.put(22, "Two");

int thirdKey = map.higherKey(map.higherKey(map.firstKey()));
System.out.println(thirdKey); // prints "33"

还要注意我是如何在intInteger 之间利用Java 的自动装箱/拆箱功能的。我注意到您在原始代码中使用了new Integernew Float;这是不必要的。


//另一个编辑

需要注意的是,如果您有多个InflatedRunner,价格相同,将只保留一个。如果这是一个问题,并且您想保留所有跑步者,那么您可以执行以下操作之一:

  • 如果您确实需要多映射(一个键可以映射到多个值),那么您可以:
    • TreeMap&lt;Float,Set&lt;InflatedRunner&gt;&gt;
    • 使用MultiMap 来自Google Collections
  • 如果您不需要地图功能,那么只需一个List&lt;RunnerPricePair&gt;(抱歉,我不熟悉该域的正确名称),其中RunnerPricePair implements Comparable&lt;RunnerPricePair&gt; 比较价格。您可以将所有对添加到列表中,然后:
    • Collections.sort列表并获得第三对
    • 使用 O(N) 选择算法

【讨论】:

  • @Daniel:我添加了使用firstKeyhigherKey 的示例。
  • 这可行,但是有一个问题..当找到两个相等的浮点数..并用作键..
  • @Daniel:是的,在这种情况下,只会保留其中一个。我假设您有某种投标方案或其他东西,并且您只需要为每个价格提供一个代表,并且您想要第三低的价格等。我添加了更多建议,希望对您有所帮助。
【解决方案2】:

您确定您使用的是正确的哈希图吗?它们用于快速查找给定键的值;对值进行排序然后尝试找到相应的键是非常不寻常的。如果有的话,您应该将浮点数映射到 int,因此您至少可以对浮点键进行排序并以这种方式获得第三小的整数值

【讨论】:

    【解决方案3】:

    你必须分步进行:

    1. 从 Map 中获取 Collection&lt;V&gt; 的值
    2. 对值进行排序
    3. 选择第 n 个最小的索引

    想想你想如何处理关系。

    【讨论】:

    • 如果您对Collection&lt;Float&gt; 进行排序,您将如何将Float“取消映射”回地图中的Integer
    【解决方案4】:

    假设浮点数是唯一的,您可以使用 google collections BiMap 来做到这一点。

    【讨论】:

      【解决方案5】:

      如果你经常需要获取第n项的key,可以考虑:

      • 使用 TreeMap,它可以有效地保持键的排序
      • 然后使用双映射(即一个 TreeMap 映射整数 > 浮点数,另一个映射浮点数 > 整数)

      您必须权衡需要维护两个映射的不优雅和潜在的错误风险,以及拥有有效保持键有序的结构的可扩展性优势。

      您可能需要考虑将两个键映射到同一个浮点数...

      附:忘了说:如果这是一个偶然的功能,你只需要找到大量项目中的第 n 个最大的项目,你可以考虑实现一个 selection 算法(实际上,你做一个排序,但实际上不必费心对您意识到不需要排序的列表子部分进行排序,因为它们的顺序对您要查找的项目的位置没有影响)。

      【讨论】:

        猜你喜欢
        • 2012-07-02
        • 1970-01-01
        • 2014-11-04
        • 1970-01-01
        • 2013-10-27
        • 1970-01-01
        • 2013-06-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多