Java中的优先级队列 - 检索特定元素

时间:2015-04-08 08:16:16

标签: java

我有一个优先级队列,其中包含一个名为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();

4 个答案:

答案 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.

  • 等于0表示比较的两个值彼此相等
  • &GT; 0表示这比作为参数
  • 给出的对象“更大”
  • &LT; 0表示这比作为参数
  • 给出的对象“小”

现在正如我已经提到的,根据你的比较方法,队列会将你试图插入的值与已经在队列中的值进行比较。

所以你要做的就是正确实施你的比较方法,正如Kiril Aleksandrov已经解释的那样。

请参阅Oracle文档https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html