【问题标题】:Getting null pointer exception when trying to merge sort array of a class尝试合并类的排序数组时出现空指针异常
【发布时间】:2020-04-24 15:54:11
【问题描述】:

我有一个名为 General 的结构良好的类,其中包含 ID、姓名和年龄的变量。两个整数和一个字符串。然后我有一个 GeneralRosters 类,它打开一个可序列化的文件,读入记录,对记录进行排序,然后关闭文件。我使用单独的 MergeSort 类对记录进行排序。每当我运行我的测试程序时,我都会不断收到 MergeSort 类的空指针异常。我知道记录已正确读入我的数组,因为我可以在读入后输出整个列表。知道出了什么问题吗?我将在下面粘贴我的代码。

import java.io.Serializable;
public class General implements Serializable {
    private int ID;
    private String name;
    private int age;
    private static final long serialVersionUID =  6894788911163027404L;   //not an instnace variable,needed for serial file

    public General() {
        setID(0);
        setName("");
        setAge(0);
    }
    public General(int ID, String name, int age) {
        setID(ID);
        setName(name);
        setAge(age);
    }
    public int getID() {
        return ID;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    public void setID(int ID) {
        this.ID = ID;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String toString() {
        return ("ID: " + ID + "\n Name: \t" + name + "\n Age: \t" + age);
    }
}
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Scanner;
public class GeneralRosters
{
    private ObjectInputStream input;
    private General [] roster = new General[20];
    // **** SORT ROUTINE *******
    public void sortRoster(){
        System.out.println("** In sortRoster **");
        MergeSort mergeSort = new MergeSort();
        mergeSort.sort(roster, 0, roster.length-1);

    }
    //  ******* OPEN FILE ROUTINE *******
    public void openFile(){
        System.out.println("** In openFile **");
        try {
            input = new ObjectInputStream(new FileInputStream("generalMaster.ser"));
        }
        catch(IOException ioException) {
            System.err.println("can't open or accesss file  " + ioException + "\n");
        }
    } 

 //******* READ FILE and LOAD ARRAY ROUTINE *******
    public void readRecords(){
        System.out.println("** In readRecords **");
        General  record;
        int count = 0;   //Used to populate array in while loop

        System.out.printf("%-12s%-20s%-12s\n","ID","Name","Age");
        try {
            while((record = (General) input.readObject()) != null)  {
                roster[count] = record;
                count++;
                System.out.printf("%-12d%-20s%-12d\n",record.getID(), record.getName(), record.getAge());
            }
        }
        catch(EOFException e){
            System.out.println("....catch ...." + e + "\n");
            return;
        }
        catch(ClassNotFoundException eclassNotFound){
            System.out.println("....catch ...." + eclassNotFound + "\n");
        }
        catch(IOException eIO){
            System.out.println("....catch ...." + eIO + "\n");
        }
    } 
    public void closeFile(){
        System.out.println("** In closeFile **");
        try {
            if (input != null)
                input.close();
        }
        catch(IOException ioExcetion) {
            System.err.println("Error closing file");
            System.exit(1);
        }
    }  
}
public class MergeSort {
    public void sort(General[] data, int low, int high) {
        if ((high - low) >= 1) {
            int middle1 = (low + high) / 2;
            int middle2 = middle1 + 1;

            sort(data, low, middle1);
            sort(data, middle2, high);

            merge(data, low, middle1, middle2, high);
        }
    }

    public void merge(General[] data, int left, int middle1, int middle2, int right) {
        int leftIndex = left;
        int rightIndex = middle2;
        int combinedIndex = left;
        General[] combined = new General[data.length];

        while (leftIndex <= middle1 && rightIndex <= right) {
            if(data[leftIndex].getID() <= data[rightIndex].getID()) {
                combined[combinedIndex++] = data[leftIndex++];
            }else {
                combined[combinedIndex++] = data[rightIndex++];
            }
        }
        if(leftIndex == middle2) {
            while(rightIndex <= right) {
                combined[combinedIndex++] = data[rightIndex++];
            }
        }else {
            while(leftIndex <= middle1) {
                combined[combinedIndex++] = data[leftIndex++];
            }
        }

        for(int i = left; i <= right; i++) {
            data[i] = combined[i];
        }
    }
}
public class GeneralRostersTest
{
    public static void main( String[] args )
    {
        GeneralRosters application = new GeneralRosters();
        application.openFile();
        application.readRecords();
        application.closeFile();
        application.sortRoster();
    }
}

【问题讨论】:

  • @ArvindKumarAvinash 我发送到我的排序方法的数组不是空的,所以我不知道为什么会出现错误。在图像中,它显示了输出到控制台的数组中的所有记录。
  • 您可以尝试在阅读循环中的原始System.out.printf 之后添加System.out.printf("%-12d%-20s%-12d\n",roster[count-1].getID(), roster[count-1].getName(), roster[count-1].getAge()); 吗?它打印什么?
  • 抱歉,在第一次编辑中,您在阅读循环中将 roster[0] 替换为 roster[count];您是否对代码应用了相同的更改?使用roster[0] 可以解释roster 数组中的null-s,即使每个record 不是null 并且可以打印出来。

标签: java arrays sorting mergesort


【解决方案1】:

在访问来自null 的数据之前,您尚未检查data[leftIndex]data[rightIndex] 中的null

替换

if(data[leftIndex].getID() <= data[rightIndex].getID()) {
    combined[combinedIndex++] = data[leftIndex++];
}

if(data[leftIndex] != null && data[rightIndex] != null) {
    if(data[leftIndex].getID() <= data[rightIndex].getID()) {
        combined[combinedIndex++] = data[leftIndex++];
    }
}

附带说明,您在阅读文件时没有检查null。当没有对象要读取时,input.readObject() 会返回null,需要在while 循环中检查,这样控件就不会进入循环体。

替换

while(true) {
    record = (General) input.readObject();

while((record = (General) input.readObject()) != null) {

【讨论】:

  • 我进行了建议的更改,但不幸的是我仍然收到相同的错误消息
  • @ConnorS。 - 我已经更新了答案。希望能解决你的问题。
  • 它现在似乎可以工作了。在我进行更改后,它起初不起作用,但 eclipse 试图运行旧版本。感谢您的帮助。
  • 但是等等,@ConnorS.,你知道为什么数组中有null-s吗?
  • @sainaen Eclipse 正在运行我的程序的旧版本,该版本没有包含我所做的任何更改。我的串行文件没有任何空值,所以它在代码中有所改变。很可能它仍在我的 readRecord 方法中使用 roster[0] 而不是 roster[count]。很抱歉造成混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 2020-11-13
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
相关资源
最近更新 更多