为什么我在运行时获得空指针异常? [重复]

问题描述 投票:1回答:2

这个问题在这里已有答案:

我正在尝试使用数组实现优先级队列堆。我在运行时遇到空指针异常错误,但我不确定为什么......?

public class PQHeap implements PriorityQueue {

Integer[] data;
private Integer numElts = 0;
private Integer temp;
private Integer k;

public PQHeap() {
    data = new Integer[2];
}

add方法将整数添加到优先级队列堆中。

public void add(Integer toAdd) {
  numElts += 1;
  if (numElts == data.length) {
        resize();
  }
  data[numElts] = toAdd;
  siftUp(numElts);

}

在整数作为堆中的最后一个元素添加后,siftUp排序。

private void siftUp(int k) {

    if (data[k/2] > data[k]) {
    }
    else {
        temp = data[k];
        data[k] = data[k/2];
        data[k/2] = temp;
        siftUp(k/2);
    }

 }


}

这是我在运行时获得的运行时错误消息...

Exception in thread "main"java.lang.NullPointerException`
       at PQHeap.siftUp(PQHeap.java:68)
       at PQHeap.add(PQHeap.java:28)
       at Tester.run(Tester.java:14)
       at Tester.main(Tester.java:94)

我也有Tester.run和Tester.main的代码,但没有发布因为我确定问题出在PQHeap中。

java priority-queue
2个回答
0
投票

我看到了几个问题。由于您的数据[0]和数据[1]尚未初始化,因此数据[0]将为空。

现在,如果在“data [numElts] = toAdd;”之后增加numElts然后你调用siftUp(numElts),

这条线在siftUp中

“if(data [k / 2]> data [k]){”

尝试读取数据[0]和数据[1],数据[1]也没有被初始化,你仍然会得到一个NullPointerException。似乎siftUp将始终访问一个元素,而不是最后一个元素初始化/填充,并且该引用将为NULL。所以你需要在siftUp中修复那个逻辑。我不完全理解你的逻辑,但也许正在移动

numElts + = 1

行到toAdd方法的末尾(调用siftUp之后)可能会解决这两个问题?新的toAdd看起来像

public void add(Integer toAdd) {
  if (numElts == data.length) {
        resize();
  }
  data[numElts] = toAdd;
  siftUp(numElts);
  numElts += 1;
}

0
投票

您的整数数组被声明为两个整数的数组,但当时两者都为null。当用1调用siftUp时,比较数据[1/2]和数据[1]。 data [1/2]对数据[0]进行评估,因此0和1是两个元素数组中的有效索引,因此没有索引超出范围的异常。

但是,此调用中的data [0] = null。要做>比较Java 5+做了一个叫做“自动拆箱”的东西,这是一个花哨的术语,用于在这个实例中获取Integer并在其上调用.intValue()。由于data [0]的计算结果为null,因此该空引用上的.intValue()会导致您的NPE。

© www.soinside.com 2019 - 2024. All rights reserved.