我有一个优先级队列,其中包含一个名为Process的自定义类型的元素。每个进程有3个字段。我需要能够从我的优先级队列中检索一个进程,该进程的某个字段具有特定值。我怎样才能做到这一点? poll()似乎总是返回队列的头部。
这是我的Process类代码:
package SPN;
public class Process implements Comparable<Process> {
@Override
public int compareTo(Process proc) {
//implement this
return 0;
}
private int arrive_time= 0;
private int burst_time = 0;
private int remain_time = 0;
public Process (int arr_time, int bur_time) {
this.arrive_time = arr_time;
this.burst_time = bur_time;
}
public int getArrTime() {return arrive_time;}
public int getBurTime() {return burst_time;}
public int getRemTime() {return remain_time;}
}
在另一个类中,我创建了一个名为prq的优先级队列,并添加了具有不同字段值的进程。不要担心代码不完整。我只是无法添加所有内容,因为它将是代码页。像这样:
p1 = new Process(2, 10);
prq.add(p1);
p2 = new Process(1, 8);
prq.add(p2);
p3 = new Process(0, 11);
prq.add(p3);
我需要能够检索进程p3,因为它具有最早的arrival_time。我怎样才能做到这一点?以下似乎只检索和删除优先级队列的头部。不要使用不同的数据结构,因为这不起作用。必须是优先级队列,因为我还需要根据其他字段进行进一步选择。
Process current = prq.poll();
答案 0 :(得分:4)
您应该像这样实施compareTo
方法:
@Override
public int compareTo(Process proc) {
// this.arriveTime > proc.arriveTime --> >0
// this.arriveTime < proc.arriveTime --> <0
// this.arriveTime = proc.arriveTime --> 0
return this.arriveTime - proc.arriveTime;
}
这样,arriveTime
较小的项目将首先出现。
答案 1 :(得分:3)
我在这里看到的原因是因为你在Process类中没有完成compareTo()方法的实现。由于它总是返回零,因此在检查每个对象相等时,检索按插入顺序排列。
您可以按照以下方式完成实施
public void compareTo(Process proc)
{
if (this.getArrTime() < proc.getArrTime()) {
return -1;
else if (this.getArrTime() > proc.getArrTime()) {
return 1;
else
return 0;
}
答案 2 :(得分:1)
Process
类没有必要实现Comparable<Process>
接口:
public class Process {
private int arrive_time= 0;
private int burst_time = 0;
private int remain_time = 0;
public Process (int arr_time, int bur_time) {
this.arrive_time = arr_time;
this.burst_time = bur_time;
}
public int getArrTime() {return arrive_time;}
public int getBurTime() {return burst_time;}
public int getRemTime() {return remain_time;}
}
PriorityQueue
名为prq
的{{1}}可以初始化为:
PriorityQueue<Process> prq = new PriorityQueue<Process>(new Comparator<Process>() {
// arrive_time in ascending order
@Override
public int compare(Process p1, Process p2) {
return p1.arrive_time - p2.arrive_time;
}
});
然后:
Process p1 = new Process(2, 10);
prq.add(p1);
Process p2 = new Process(1, 8);
prq.add(p2);
Process p3 = new Process(0, 11);
prq.add(p3);
System.out.println(prq.poll().getArrTime()); // output is 0 (which means p3)
System.out.println(prq.poll().getArrTime()); // output is 1 (which means p2)
答案 3 :(得分:1)
PriorityQueue的目的是拥有按优先级排序的元素集合。在您的情况下,最早到达的流程具有最高优先级。将元素添加到PriorityQueue时,它将与已经在队列中的其他元素进行比较并放在正确的位置。
现在我觉得我们对比较对象仍然有点不清楚,所以这里有一点解释: 比较方法(由于Comparator接口必须实现)总是返回一个int值,即&lt; 0,等于0或> 0.
现在正如我已经提到的,根据你的比较方法,队列会将你试图插入的值与已经在队列中的值进行比较。
所以你要做的就是正确实施你的比较方法,正如Kiril Aleksandrov已经解释的那样。
请参阅Oracle文档https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html