【问题标题】:Priority Queue using MultiMap - Java使用 MultiMap 的优先级队列 - Java
【发布时间】:2012-10-15 23:02:21
【问题描述】:

我必须使用 MultiMap 实现优先队列。我使用 Google Collections 中的 MultiMap。 以下代码创建了一个 MultiMap 并在其中添加了一些元素。

    Multimap<Integer, String> multimap = HashMultimap.create();

    multimap.put(5,"example");
    multimap.put(1,"is");
    multimap.put(1,"this");
    multimap.put(4,"some");

现在我的问题是如何编写pop方法?

我认为应该有一个 for 循环,它应该通过 MultiMap 进行迭代。

最低的键应该是最高的优先级,所以在 C++ 中我会设置一个指向第一个元素的指针并递增它。用Java怎么做?

【问题讨论】:

    标签: java priority-queue guava multimap


    【解决方案1】:

    您使用的HashMultimap 不会为您有效选择最低元素提供任何帮助。而是使用TreeMultimap(也在Google Collections 中),它允许您指定排序并按该顺序遍历列表中的项目。例如:

    for (Map.Entry<Integer, String> entry : multimap.entries()) {
      System.out.println("Item " + entry.getValue() + " has priority " + entry.getKey();
    }
    

    您会注意到这总是按优先级顺序打印出条目,因此要获得第一优先级元素,您只需执行multimap.entries().iterator().next()(假设您知道地图至少有一个元素)。

    更多信息请参见the TreeMultimap documentation

    【讨论】:

    • 谢谢,这很有用,但是如何遍历 TreeMultiMap?
    • 使用multimap.entries() 并使用其iterator() 方法对其进行迭代。我会更新答案。
    • 我认为这是最后一个问题:我可以通过:System.out.println(multimap.entries().iterator().next()); 显示对象,现在如何删除这个第一优先级元素(就像 pop 方法通常那样)?
    • 最简单的方法就是使用multimap.remove(key, value)
    • 感谢您的回答,jacobm。我终于完成了。
    【解决方案2】:

    如果我正确理解您使用 Multimap 作为您自己的 PriorityQueue 类的内部,而不是仅仅尝试使用 Multimap 作为优先级队列,那么您可能应该保留一个 SortedSet(我将其称为 sortedKeys ) 的所有键。然后你可以使用 multimap.get(sortedKeys.first()) 弹出第一个元素。

    “保持一个 SortedSet”,我的意思是每次你向 Multimap 添加一些东西时,将它的键添加到一个 SortedSet。当您从 Multimap 中删除项目时,请从 SortedSet 中删除它们的键。目标是您的 SortedSet 保持等于 Multimap.keySet(),但没有一直调用 SortedSet.clear(); SortedSet.addAll(...) 的开销。

    另一种方法是每次都创建一个 SortedSet,这会慢得多。不过,它可能会帮助您理解我在说什么:

    public Collection<V> pop() {
        SortedSet keys = new TreeSet(multimap.keySet());
        return multimap.get(keys.first());
    }
    

    【讨论】:

    • 问题是我必须在这个项目中使用MultiMap:/
    • jacobm 的答案更简单,因为 TreeMultimap 已经为您完成了所有这些工作。我对谷歌收藏不是很熟悉,所以我没有意识到他们已经有一个这样做的课程。
    • SortedSet 是否可以包含两个或多个相同的键,就像在 MultiMap 中可能发生的那样?
    • 集合没有“键”,它们只有元素,是的,你可以有重复的元素。
    【解决方案3】:

    你能简单地使用 JDK 中的PriorityQueue 类吗?

    使用 jacobm 建议的 TreeMultimap 方法,下面的代码更简洁。

    Iterator<String> iterator = multimap.values().iterator();
    String value = iterator.next();
    iterator.remove();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多