【问题标题】:NullPointerException in an Array Stack数组堆栈中的 NullPointerException
【发布时间】:2014-05-17 08:50:06
【问题描述】:

我正在尝试为反转声音剪辑的程序使用数组实现堆栈,将 .dat 文件的所有部分放入堆栈中,然后将它们逐个弹出。每当我运行客户端程序时,我的 pop() 方法中都会出现 NullPointerException,但我不知道为什么。

这是我的堆栈实现:

import java.util.EmptyStackException;
public class ArrayStack 
implements DStack {
private int size = 0;
private static int DEFAULT_CAPACITY = 10;
private Double ArraySt[];


public ArrayStack(){
    ArraySt = new Double[DEFAULT_CAPACITY];
}


public boolean isEmpty(){
    boolean empty = true;
    if(ArraySt.length != 0) {
        empty = false;
    }

    return empty;

}
public void push(double d){
    if(size == ArraySt.length){
        increaseCapacity();
    }
    ArraySt[size++] = d;

}
public double pop(){
    boolean empty = isEmpty();
    if(empty == true){
        throw new EmptyStackException();
    }
    double d = ArraySt[--size];
    ArraySt[size] = null;
    return d;

}

public double peek(){
    boolean empty = isEmpty();
    if(empty == true){
        throw new EmptyStackException();
    }
    double stackTop = pop();
    return stackTop;

}
private Double[] increaseCapacity(){
    int arrayLength = ArraySt.length;       
    int newCapacity = ArraySt.length*2;
    Double[] increaseArray = new Double[newCapacity];
    for(int i = 0; i < arrayLength; i++){
        ArraySt[i] = increaseArray[i];

    }
    return increaseArray;
}


}

这是客户端程序:

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.StringTokenizer;

/**
 * Read a .dat file and reverse it.
 * 
 * @version CSE373, 14sp
 */
public class ReverseRedux {

    @SuppressWarnings("unused")
    public static void main(String[] args) {
        if (args.length != 3) {
            System.err.println(" Incorrect number of arguments");
            System.err.println(" Usage: ");
            System.err
                    .println("\tjava Reverse <stack type> <input file> <output file>");

            System.exit(1);
        }

        boolean useList = true;
        if (args[0].compareTo("list") == 0)
            useList = true;
        else if (args[0].compareTo("array") == 0)
            useList = false;
        else {
            System.err.println("\tSaw " + args[0]
                    + " instead of list or array as first argument");
            System.exit(1);
        }

        try {
            //
            // Set up the input file to read, and the output file to write to
            //
            BufferedReader fileIn = new BufferedReader(new FileReader(args[1]));
            PrintWriter fileOut = new PrintWriter(new BufferedWriter(
                    new FileWriter(args[2])));

            //
            // Read the first line of the .dat file to get sample rate.
            // We want to store the sample rate value in a variable,
            // but we can ignore the "; Sample Rate" part of the line.
            // Step through the first line one token (word) at a time
            // using the StringTokenizer. The fourth token is the one
            // we want (the sample rate).
            //
            StringTokenizer str;
            String oneLine;
            int sampleRate;
            String strJunk;

            oneLine = fileIn.readLine();

            str = new StringTokenizer(oneLine);
            strJunk = str.nextToken(); // Read in semicolon
            strJunk = str.nextToken(); // Read in "Sample"
            strJunk = str.nextToken(); // Read in "Rate"

            // Read in sample rate
        sampleRate = Integer.parseInt(str.nextToken());

        //
        // Read in the remainder of the file on line at a time.
        // The values in the first column are thrown away.
        // Place values from the second column on the stack.
        // Stop reading if we reach the end of the file.
        //

        DStack s;
        if (useList)
            s = new ListStack();
        else
            s = new ArrayStack();
        String timestep;
        double data;

        int count = 0;
        while ((oneLine = fileIn.readLine()) != null) {
            if (oneLine.charAt(0) == ';') {
                continue;
            }
            str = new StringTokenizer(oneLine);

            // Read in time step value from first column
            timestep = str.nextToken();
            // Read in data value from second column
            data = Double.parseDouble(str.nextToken());
            s.push(data);
            count++;
        }

        System.out.println(count + " samples in file");

        //
        // Print the data values to output .dat file.
        // First, output the header line:
        // "; Sample Rate <sample rate>"
        //
        fileOut.println("; Sample Rate " + sampleRate);

        // Since the first column consists of numbers which start
        // at 0 and increase by 1/sampleRate every time slice, we'll
        // just use numSteps to recalculate these numbers.
        int numSteps = 0;

        // Finally, we print the values in reverse order (by popping
        // them off the stack). The first column consists of numbers
        // which start at 0 and increase by 1/sampleRate per row, so
        // we'll use numSteps/sampleRate to recalculate the appropriate
        // values. Print a tab for uniform spacing.

        while (!s.isEmpty()) {
            fileOut.println((double) numSteps / sampleRate + "\t" + s.pop());
            numSteps++;
        }

        //
        // Close the files
        //
        fileIn.close();
        fileOut.close();

    } catch (IOException ioe) {
        System.err
                .println("Error opening/reading/writing input or output file.");
        System.exit(1);
    } catch (NumberFormatException nfe) {
        System.err.println(nfe.toString());
        System.err.println("Error in file format");
        System.exit(1);
    }
}

}

感谢您的帮助!

【问题讨论】:

  • 你也可以发布你的堆栈跟踪吗?
  • 你的堆栈跟踪在哪里?它来自哪条线路?
  • 异常应该告诉你确切的位置。使用调试器可以让您准确了解发生了什么。

标签: java arrays nullpointerexception stack


【解决方案1】:

我猜这行是原因:

double d = ArraySt[--size];

你在这个数组位置有 null 并将其转换为原始会导致 NPE

【讨论】:

    【解决方案2】:

    问题可能与peek() 方法有关,您在内部调用pop() 方法。这就是为什么size设置错误,通过ArraySt[size]获取值时会导致空指针异常。

    要解决这个问题,请在构造时初始化数组的所有元素。使用默认值。

     public ArrayStack(){
            ArraySt = new Double[DEFAULT_CAPACITY];
            for(int i=0;i<DEFAULT_CAPACITY;i++){
                ArraySt[i]=0.0;
            }
      }
    

    【讨论】:

      【解决方案3】:

      我看到两个问题:

      1) 你在哪里设置size?目前,它为零,这将导致数组索引异常。也许你的意思是这样做:

      public ArrayStack() {
          ArraySt = new Double[DEFAULT_CAPACITY];
          size = ArraySt.length;
      }
      

      2) ArraySt 的内容在哪里设置?如果不设置数组的内容,在此处拆箱 Double 时会出现 NullPointerException:

      double d = ArraySt[--size];
      

      【讨论】:

      • isEmpty() 看起来也不太好 - 数组在哪里减少?
      • 谢谢,我在构造函数中将数组中的所有元素初始化为0.0。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 2020-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 2018-06-06
      相关资源
      最近更新 更多