我想增加或降低PriorityQueue
中项目的优先级:例如,我可能正在下载一长串图像,并突然希望第三十个图像具有最高优先级。
据我了解,poll()
总是返回具有最低值的队列对象(由比较器确定)。如果我可以降低队列中已有项目的值(例如,如果此值由对象中的int
确定,并且我在某个其他函数中减少int
值),是否会返回首先是poll()
,或者是允许poll()
在插入时完成此操作的排序(例如,通过在列表中冒泡新队列元素直到它们达到“自然”深度)?
如果在PriorityBlockingQueue
上完成此操作,是否会导致并发问题?
答案 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)
如果迭代优先级队列,您会发现它没有特定的顺序(第一个元素除外)如果您想更改顺序,我建议您创建另一个优先级队列。
如果您想更改一个条目的位置,我建议您将其删除,根据需要更改其字段并重新添加。