【问题标题】:how to fix NullPointerException in generic circular array queue [duplicate]如何修复通用循环数组队列中的 NullPointerException [重复]
【发布时间】:2020-06-24 23:03:22
【问题描述】:

我正在尝试使用两个队列创建一个基本的机场模拟。它们应该在起飞之间交替,当一个没有更多“飞机”时,需要处理 NPE,以便另一个队列可以继续运行,直到循环完成并且两个队列都用完,因为一个有 7条目,另一个有 4 个。我想如果我尝试在 dequeue 方法中放置一个异常处理程序,它可能会修复它,但是我必须为它使用一个泛型类,所以它不能正常工作。截至目前,用于出队的 for 循环一直运行到第 4 个循环,也就是它停止、抛出 NPE 并退出程序的时候。所以我的问题是,我怎样才能做到这一点,当一个队列用完时,它会停止尝试循环它,而是继续循环最后一个队列?

这是我运行循环的主类:

public abstract class Airport<T> {

    public static void main(String[] args) {
        //creates separate queues
        Driver<Integer> runway1 = new Driver<>();
        Driver<Integer> runway2 = new Driver<>();

        //adds 7 planes into runway 1
        for (int i = 0; i < 7; i++) {
            runway1.enqueue(i);
        }

        //adds 4 planes into runway 2
        for (int i = 0; i < 4; i++) {
            runway2.enqueue(i);
        }

        int size1 = runway1.length();
        int size2 = runway2.length();

        //run loop while either runway has planes left
        while (size1 > 0 && size2 > 0) {
            System.out.println("There are currently " + size1 + " planes waiting for takeoff in Runway 1.");
            System.out.println("There are currently " + size2 + " planes waiting for takeoff in Runway 2.\n");


            for (int lane = 0; lane < 7; lane++) {
                int lane1, lane2;

                if (runway1.isEmpty()){
                    System.out.println("Runway 1 is empty.");
                }
                else {
                    lane1 = runway1.getFront();
                    System.out.println("Plane " + lane1 + " has taken off from Runway 1.");
                    runway1.dequeue();
                }

                if (runway2.isEmpty()){
                    System.out.println("Runway 2 is empty.");
                }
                else{
                    lane2 = runway2.getFront(); //EDIT: npe occurs here
                    System.out.println("Plane " + lane2 + " has taken off from Runway 2.\n");
                    runway2.dequeue();
                }

            }
        }

    }

}

这是我的驱动程序类的一部分:

class Driver<T> implements Queue1<T> {
    private static final int defaultSize = 10;
    private int maxSize; // Maximum size of queue
    private int front; // Index of front element
    private int rear; // Index of rear element
    private T[] listArray; // Array holding queue elements

    /**
     * Constructors
     */
    Driver() {
        this(defaultSize);
    }

    @SuppressWarnings("unchecked")
        // For generic array
    Driver(int size) {
        maxSize = size + 1; // One extra space is allocated
        rear = 0;
        front = 1;
        listArray = (T[]) new Object[maxSize]; // Create listArray
    }

    /**
     * Put "it" in queue
     */
    public void enqueue(T it) {
        assert ((rear + 2) % maxSize) != front : "Queue is full";
        rear = (rear + 1) % maxSize; // Circular increment
        listArray[rear] = it;
    }

    /**
     * Remove and return front value
     **/
    public T dequeue() {
        assert length() != 0 : "Queue is empty";
        T it = listArray[front];
        front = (front + 1) % maxSize; // Circular increment
        return it;
    }

    /**
     * Return Front Value
     **/
    @Override
    public T getFront() {
        assert length() != 0 : "Queue is empty";
        return listArray[front];
    }

    @Override
    public T getBack() {
        assert length() != 0 : "Queue is empty";
        return listArray[rear];
    }

    @Override
    public boolean isEmpty() {
        if(listArray == null){
            return true;
        }
        return false;
    }

    /**
     * @return Queue length
     **/
    public int length() {
        return ((rear + maxSize) - front + 1) % maxSize;
    }


}


这几天我一直在摸不着头脑,所以任何帮助都将不胜感激!谢谢!

【问题讨论】:

  • NPE 发生在哪里?
  • @dan1st 我的错,更新它以显示它在“lane2 = runway2.getFront();”的位置
  • Driver 的getFront() 方法在哪里?
  • Driver#getFront的代码是什么?你确定这就是它发生的确切位置吗?
  • 我认为您应该使用(T[])java.reflect.Array.newInstance(T.class,maxSize); 来实例化数组...参见stackoverflow.com/questions/529085/…

标签: java arrays for-loop nullpointerexception queue


【解决方案1】:

问题是您的isEmpty() 方法无法按您希望的方式工作。您正在使用它,就好像它检查队列中是否有任何东西,但它被写入执行其他操作。假设你的length()方法是正确的,你需要检查length() == 0是否正确。如果是这样,那么您应该返回 true。如果不是,则应返回 false。

您收到 NullPointerException 的原因是因为您假设列表不为空,因此您尝试访问队列中的下一个内容,即null

在代码中,它看起来像这样:

public boolean isEmpty() {
   return length()==0;
}

【讨论】:

  • 哦,这就是问题所在!一旦我将 while 循环条件更改为 (!runway1.isEmpty() && !runway2.isEmpty()) 它就开始完美运行!非常感谢!
【解决方案2】:

我没有你的驱动程序类,所以我只用了可用的东西:

public static void main(String [] args) {
    ArrayDeque<Integer> runway1 = new ArrayDeque<>();
    ArrayDeque<Integer> runway2 = new ArrayDeque<>();
    //adds 7 planes into runway 1
    for (int i = 0; i < 7; i++) {
        runway1.offer(i);
    }

    //adds 4 planes into runway 2
    for (int i = 0; i < 4; i++) {
        runway2.offer(i);
    }

    //run loop while either runway has planes left
    String waitingMsg = "There are currently %d planes waiting for takeoff in Runway %d.";
    while (!runway1.isEmpty() && !runway2.isEmpty()) {
        System.out.println(String.format(waitingMsg, runway1.size(), 1));
        System.out.println(String.format(waitingMsg, runway2.size(), 2));
        System.out.println();

        for (int lane = 0; lane < 7; lane++) {
            if (runway1.isEmpty()){
                System.out.println("Runway 1 is empty.");
            } else {
                int lane1 = runway1.pop();
                System.out.println("Plane " + lane1 + " has taken off from Runway 1.");
            }

            if (runway2.isEmpty())  {
                System.out.println("Runway 2 is empty.");
            } else{
                int lane2 = runway2.pop();
                System.out.println("Plane " + lane2 + " has taken off from Runway 2.\n");
            }

        }
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多