java - 使 Java PriorityQueue 成为稳定的优先级队列

标签 java linked-list queue priority-queue comparator

我正在尝试用 Java 实现一个稳定的(先进先出)优先级队列。假设键是一个名字,值是一个年龄,我知道我可以像这样创建一个不稳定的优先级队列:

Queue<Map.Entry<String, Integer>> pq = new PriorityQueue<Map.Entry<String, Integer>>(100, ageComparator);

这几乎完成了我需要它做的所有事情,除了它在我插入(或删除)键值对时不维护键值对的顺序。

我通过创建一个 LinkedList 找到了一个“变通办法”,它提供了基本上所有相同的功能,只是它不包括一个带有比较器选项的构造函数,而且我觉得它一定更慢,因为我通过在每次队列操作后调用 Collections.sort() 来维护值排序。

所以我想我真的有两个选项感兴趣。首先,我如何编辑上面的 PriorityQueue 以维护插入和删除顺序?或者其次,我如何强制我的 LinkedList 选项立即使用比较器而不是必须对每个操作调用排序?谢谢!

编辑:

感谢您在第一条评论中提出的好问题。所谓 FIFO,我的意思是对于具有相等值的键值对,先放入的对应该先提取。

最佳答案

你需要这样的东西:

import java.util.AbstractMap;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class PriorityTest {
  @SuppressWarnings("serial")
  private static class Entry extends AbstractMap.SimpleEntry<String, Integer> {
    private final static AtomicInteger seq = new AtomicInteger(0);
    final int order;
    public Entry(final String _key, final Integer _value) {
      super(_key, _value);
      order = seq.incrementAndGet();
    }
  }

  private static class OrderedComparator implements Comparator<Entry> {
    @Override
    public int compare(final Entry _e1, final Entry _e2) {
      int r = _e1.getValue().compareTo(_e2.getValue());
      if (r == 0)
        return Integer.compare(_e1.order, _e2.order);
      return r;
    }
  }

  public static void main(String[] args) {
    final PriorityQueue<Entry> pq = new PriorityQueue<Entry>(10, new OrderedComparator());
    pq.add(new Entry("Jane", 22));
    pq.add(new Entry("John", 15));
    pq.add(new Entry("Bill", 45));
    pq.add(new Entry("Bob", 22));
    while(!pq.isEmpty()) {
      System.out.println(pq.remove());
    }
  }
}

关于java - 使 Java PriorityQueue 成为稳定的优先级队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21617098/

相关文章:

java - 无法在我的系统中配置 Struts

java - LibGDX 标签不绘图

java - 按字母顺序插入链表

iPhone:启动时加载队列

Laravel 作业虽然已完成,但仍处于 "Processing"状态

c++ - 洗车队列问题

java - 无法更新我的 Map<String, Deque<Block>>

java - 如何从 DKPro/UIMA 中的句子中获取引理?

c++ - 理解/创建链表

c - 学习C,[1]为什么要在main中获得无限循环? [2]为什么在不触摸文件检查代码的情况下出现段错误