在优先级队列的实现中比较对象的属性

时间:2017-02-03 17:21:23

标签: java priority-queue

我尝试使用对象数组"队列项"来实现优先级队列。它有一些数据(字符串)和一个优先级的整数。我正在努力使这些项目具有可比性,以便当我向队列中添加新对象时,我可以遍历项目并将新项目添加到正确的位置并将所有现在后面的项目向后移动,但是当我添加一个新项目到队列我得到一个空指针异常。我将包含我的所有代码,但是toString方法只是从队列中复制而来,所以它不会按预期工作。

class QueueItem implements Comparable<QueueItem> {
    String data;
    int pri;

    public QueueItem(String data, int pri) {
        this.data = data;
        this.pri = pri;
    }

    @Override
    public int compareTo(QueueItem item) {
        return this.data.compareTo(item.data);
    }
}

public class PriorityQueue implements Queue<String> {
    private QueueItem[] arr;
    private int frontPos, backPos;

    public PriorityQueue() {
        arr = new QueueItem[20];
        backPos = -1;
        frontPos = 0;
    }

    public boolean isEmpty() {
        return frontPos == (backPos + 1) % arr.length;
    }

    public String front() {
        if (frontPos == (backPos + 1) % arr.length)
            throw new QueueException("Empty Queue - front");
        return arr[frontPos].data;
    }

    public int frontPri() {
        if (frontPos == (backPos + 1) % arr.length)
            throw new QueueException("Empty Queue - frontPri");
        return arr[frontPos].pri;
    }

    public void addToPQ(String str, int x) {
        if (arr.length==0) {
            arr[frontPos] = new QueueItem(str, x);
            frontPos++;
            return;
        }
        else {
            for (int i = 0; i < arr.length; i++) {
                arr[i].compareTo(new QueueItem(str, x));
            }
        }
    }

    public void deleteFront() {
        if (frontPos==(backPos+1)%arr.length) {
            throw new QueueException("Empty Queue - deleteFront");
        }
        frontPos = (frontPos+1)%arr.length;
    }

    public String toString() {
        if (frontPos == (backPos + 1) % arr.length) {
            return "<>";
        }
        StringBuffer sb = new StringBuffer();

        sb.append('<');

        int pos = frontPos;
        while (pos != backPos) {
            sb.append(arr[pos]);
            sb.append(',');
            pos = (pos + 1) % arr.length;
        }

        sb.append(arr[backPos]);
        sb.append('>');

        return (sb.toString());
    }
}

public interface Queue<String> {
    public void addToPQ(String str, int x);

    public void deleteFront();

    public String front();

    public boolean isEmpty();

    public int frontPri();
}

class QueueException extends RuntimeException {
    QueueException(String s) {
        super("Tried to apply " + s + " to empty queue");
    }
}

public class pqTest {
    public static void main(String[] args) {
        PriorityQueue pQ = new PriorityQueue();
        if (pQ.isEmpty()) {
            System.out.println("Queue is Empty - isEmpty");
        }
        pQ.addToPQ("Dog", 4);
        pQ.addToPQ("Cat", 20);
        pQ.deleteFront();
        pQ.addToPQ("Fish", 2);
    }
}

2 个答案:

答案 0 :(得分:1)

问题是arr的大小为20,因此第一个元素甚至不会通过addToPQ方法中的if语句添加,因为arr.length != 0。所以它将转到你的else语句,它会遍历arr中的每个元素。但是arr有20个空元素,因为QueueItems数组中的每个点都没有被初始化。因此,您应该将if语句中的条件更改为frontPos == 0,并将循环中的终止条件更改为i < frontPos,以便该方法不会遍历arr中的空元素

public void addToPQ(String str, int x) {
        if (frontPos==0) {
            arr[frontPos] = new QueueItem(str, x);
            frontPos++;
            return;
        }
        else {
            QueueItem item = new QueueItem(str, x);
            for (int i = 0; i < frontPos; i++) {
                arr[i].compareTo(item);
            }
        }
    }

答案 1 :(得分:0)

你得到NullPointerException,因为当你添加第二个项目时,你会转到else语句,你用一个非null元素和19个空值迭代数组。因此,您需要更改代码以检查 i 中的数组元素是否为空,如果是,则为其分配新元素。