PriorityQueue是否允许重新排序队列中已有的元素?

时间:2011-11-09 16:13:30

标签: java priority-queue

我想增加或降低PriorityQueue中项目的优先级:例如,我可能正在下载一长串图像,并突然希望第三十个图像具有最高优先级。

据我了解,poll()总是返回具有最低值的队列对象(由比较器确定)。如果我可以降低队列中已有项目的值(例如,如果此值由对象中的int确定,并且我在某个其他函数中减少int值),是否会返回首先是poll(),或者是允许poll()在插入时完成此操作的排序(例如,通过在列表中冒泡新队列元素直到它们达到“自然”深度)?

如果在PriorityBlockingQueue上完成此操作,是否会导致并发问题?

3 个答案:

答案 0 :(得分:6)

如果更改确定其顺序的属性,则Java中的任何集合都不会自动重新排序元素。对于依赖于.hashCode(),. equals()或某个比较器的集合,当对象驻留在集合中时,不允许更改对象,以便hashcode / equals或者比较器产生不同的值。

如果要在PriorityQueue中更改其优先级,则必须删除,更改,重新插入对象。

答案 1 :(得分:2)

如果您查看源代码,每次poll() PriorityQueue它会重新启动,但它总是在筛选前返回 的项目

public class PQ {

  int priority;

  public PQ(int priority) {
    this.priority = priority;
  }

  public static void main(String[] args) {

    PQ one = new PQ(1);
    PQ two = new PQ(2);
    PQ three = new PQ(3);
    PQ four = new PQ(4);
    PQ five = new PQ(5);

    PriorityQueue<PQ> q = new PriorityQueue<PQ>(3, new Comparator<PQ>() {
      @Override
      public int compare(PQ o1, PQ o2) {
        return o1.priority-o2.priority;
      }
    });

    q.add(three);
    q.add(one);
    q.add(four);
    q.add(two);
    q.add(five);

    //Prints;
    //PQ-1
    //PQ-2
    //PQ-3
    //PQ-4
    //PQ-5
    while (!q.isEmpty()) {
      System.out.println(q.poll());
    }

    q.add(three);
    q.add(one);
    q.add(four);
    q.add(two);
    q.add(five);

    //Change the priority after it has been queued
    four.priority = 10;

    //Prints;
    //PQ-1
    //PQ-2
    //PQ-3
    //PQ-5
    //PQ-10
    while (!q.isEmpty()) {
      System.out.println(q.poll());
    }

    //Reset the priority
    four.priority = 4;

    q.add(three);
    q.add(one);
    q.add(four);
    q.add(two);
    q.add(five);

    //Change the priority after it has been queued
    four.priority = 0;

    //Prints;
    //PQ-1
    //PQ-0
    //PQ-2
    //PQ-3
    //PQ-5
    while (!q.isEmpty()) {
      System.out.println(q.poll());
    }
  }

  public String toString() {
    return "PQ-" + priority;
  }

}

答案 2 :(得分:0)

如果迭代优先级队列,您会发现它没有特定的顺序(第一个元素除外)如果您想更改顺序,我建议您创建另一个优先级队列。

如果您想更改一个条目的位置,我建议您将其删除,根据需要更改其字段并重新添加。