获取ArrayOutOfBounds和NullPointerException但我不知道为什么

时间:2017-03-02 18:58:45

标签: java arrays object

我正在测试我为作业编写的程序,现在它正在测试50%的测试用例。我提交时收到以下错误,但我无法弄清楚原因。我尝试更改一些代码并重新测试,但无论我做什么,我都会得到相同的错误,所以我必须完全忽略我应该寻找的东西。以下是从中提取数据的CSV文件 - CSV Data File。以下是我得到的错误:

enter image description here

这是我的代码:

主要课程:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package csc212hw04;
import java.io.File;
import java.util.Scanner;
/**
 *
 * @author Michal
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception{
        Scanner kb = new Scanner(System.in);
        boolean flag = true;

        System.out.println("Welcome to the Car Database");
        System.out.println("Enter the size of the array:");
        int size = Integer.parseInt(kb.nextLine());
        CarDatabase db1 = new CarDatabase(size);

        System.out.println("Enter the name of the input file:");
        String userFile = new String(kb.nextLine());
        db1.readFile(userFile);

        while (flag) {
            System.out.println("Enter make, mpg, weight, all, or quit:");
            String command = kb.nextLine();
            if (command.equals("make")) {
                System.out.println("Enter the make:");
                String make = kb.nextLine();
                db1.displayMake(make);
            } else if (command.equals("mpg")) {
                System.out.println("Enter the mpg range:");
                double mpgLow = Double.parseDouble(kb.nextLine());
                double mpgHigh = Double.parseDouble(kb.nextLine());
                db1.mpgRange(mpgLow, mpgHigh);
            } else if (command.equals("weight")) {
                System.out.println("Enter the weight range:");
                double weightLow = Double.parseDouble(kb.next());
                double weightHigh = Double.parseDouble(kb.next());
                db1.weightRange(weightLow, weightHigh);
            } else if (command.equals("all")) {
                CarDatabase.displayAll();
            } else if (command.equals("quit")) {
                flag = false;
            }
        }


    }

}

CarDatabase类:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package csc212hw04;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
/**
 *
 * @author Michal
 */
public class CarDatabase {
    private static Car[] database;

    public CarDatabase(int s) {
       this.database = new Car[s];
    }

    public boolean isFull() {
        boolean full = true;

        for (int i = 0; i < database.length; i++) {
            if (database[i] == null) {
                full = false; 
            }
        }

        return full;
    }

    public static void readFile(String f) throws FileNotFoundException {
        File file = new File(f);
        int lineNum = 0;
        Scanner sc = new Scanner(file);
        String csvSplitBy = ",";

        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            String[] carData = line.split(csvSplitBy);
            String model = carData[0];
            String make = carData[1];
            double mpg = Double.parseDouble(carData[2]);
            int weight = Integer.parseInt(carData[3]);
            int year = Integer.parseInt(carData[4]);
            database[lineNum] = new Car(model, make, mpg, weight, year);
            lineNum++;
        }
    }

    public static void displayMake(String m) {
        for (int i = 0; i < database.length; i++) {
            if (database[i].make.equals(m)) {
                database[i].toString();
            }
        }
    }

    public static void mpgRange(double l, double h) {
        for (int i = 0; i < database.length; i++) {
            if (database[i].mpg >= l && database[i].mpg <= h) {
                database[i].toString();
            }
        }
    }

    public static void weightRange(double l, double h) {
        for (int i = 0; i < database.length; i++) {
            if ((database[i].weight >= l) && (database[i].weight <= h)) {
                database[i].toString();
            }
        }
    }

    public static void displayAll() {
        for (int i = 0; i < database.length; i++) {
            database[i].toString();
        }
    }
}

汽车类:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package csc212hw04;

/**
 *
 * @author Michal
 */
public class Car {
    public String model, make;
    public double mpg;
    public int weight, year;

    public Car(String md, String mk, double umpg, int w, int y) {
        model = md; 
        make = mk;
        mpg = umpg;
        weight = w;
        year = y;
    }

    public String toString() {
        return "Model:" + model + " Make:" + make + " mpg:" + " weight:" + " year:" + year;
    }
}

以下是CSV文件中的示例,如果您看不到它:

enter image description here

2 个答案:

答案 0 :(得分:2)

您可能已经到了文件结尾并尝试拆分。然后该数组没有任何值。确保数据库末尾没有空行,或者检查readfile以确保carData.length == NUMBER OF DATA FIELDS

更新

您还应该检查以确保没有传递您拥有的数据库条目总数。所以:

while(sc.hasNextLine() && lineNum < database.length) {

答案 1 :(得分:1)

在非常特殊的情况下抛出ArrayIndexOutOfBoundsException:

  

抛出表示已使用非法访问数组   指数。该指数为负数或大于或等于   数组的大小。

在您的代码中,您假设csv中的每一行都有相同数量的字段。

您还假设数据库阵列的大小与文件中的汽车数量相匹配。由于在从文件中读取它们之前不创建数据库数组条目 - 但是预先初始化大小数据库数组,如果CSV中的记录数大于,则最终可能会读取数据库的末尾。您初始化数据库大小的值。