2013-10-27 37 views
1

哎Ive得到了應該csv文件的加載行到對象的數組的代碼多數民衆贊成在一大塊:存儲一個CSV對象到一個數組

public static WarehouseItem[] loadRecords(WarehouseItem[] records) { 
    FileInputStream fileStrm = null; 
    InputStreamReader rdr; 
    BufferedReader bufRdr; 
    int numRows = 0; 
    String warehouseItem; 
    String filename; 

    filename = ConsoleInput.readLine("Please enter the filename (DataMillion.csv OR DataThousand.csv)"); 

    try { 
    fileStrm = new FileInputStream(filename); 
    rdr = new InputStreamReader(fileStrm); 
    bufRdr = new BufferedReader(rdr); 

    warehouseItem = bufRdr.readLine(); 
    records[numRows] = new WarehouseItem(warehouseItem); //NULL POINTER EXCEPTION HERE 
    System.out.println(records[0].toString(records[0].columnVals)); 
    while (warehouseItem != null) { 
     numRows++; 
     records[numRows] = new WarehouseItem(warehouseItem); 
     warehouseItem = bufRdr.readLine(); 
    } 
    fileStrm.close(); 
    } 

    catch (IOException e) { 
    if (fileStrm != null) { 
     try { 
    fileStrm.close(); 
     } catch (IOException ex2) {} 
    } 
    System.out.println("Error in file processing: " + e.getMessage()); 
    } 
    main(null); 
    return records; 
} 

但是當我運行它,我得到一個NullPointerException異常上線

records[numRows] = new WarehouseItem(warehouseItem);

有什麼,我錯過了?

繼承人的WarehouseItem構造+的toString:

public class WarehouseItem { 
    String[] columnVals; 
    int numColumns = 5; 

public WarehouseItem(String warehouseItem) { 
    String key, brand, model, price, weightInKG; 
    int intWeightInKG; 
    double doublePrice; 
    StringTokenizer strTok; 

    strTok = new StringTokenizer(warehouseItem, ","); 
    key = strTok.nextToken(); 
    brand = strTok.nextToken(); 
    model = strTok.nextToken(); 
    intWeightInKG = Integer.parseInt(strTok.nextToken()); 
    doublePrice = Double.valueOf(strTok.nextToken()); 

    weightInKG = String.valueOf(intWeightInKG); 
    price = String.valueOf(doublePrice); 
    String[] columnVals = {key, brand, model, weightInKG, price}; 

    if(columnVals.length != 5) 
    throw new IllegalStateException("Invalid CSV: not enough columns"); 
} 

public String toString(String[] columnVals) { 
    return ("Key:  " + columnVals[0] + "\n" + 
     "Brand: " + columnVals[1] + "\n" + 
     "Model: " + columnVals[2] + "\n" + 
     "Weight: " + columnVals[3] + "\n" + " kg" + 
     "Price: " + "$" + columnVals[4] + "\n"); 
} 
} 

我的問題是什麼值都沒有得到存儲在陣列記錄正確和IM不知道爲什麼

+0

我如何初始化它,這樣的記錄的最大數量爲1000000(100萬) –

回答

1

當您創建對象的數組在Java中,它被初始化爲全部空值。這就是爲什麼你得到一個nullpointerexception。

所以你需要爲每個陣列位置創建一個對象。事實上,不用調用一個方法就可以讓該方法成爲構造函數;那會更簡單。

我還注意到另一個錯誤:該方法設置局部變量,它只存在於該方法的生命週期中,實際上它應該設置實例變量。

然後我發現了第三個錯誤:您剛剛發現了異常,並且認爲那表示缺少列;實際上它可能表示列中的無效數據類型(例如字符串而不是整數)。

+0

嘿感謝你的反饋,但什麼你的意思是讓方法成爲構造函數嗎?對不起,我相當新 –

+0

你知道什麼是構造函數嗎? –

+0

耶只是有點熟悉它 –

1

你錯過了對象創建records[numRows]=new WarehouseItem();

您的代碼必須是這樣。

while (warehouseItem != null) { 
     records[numRows]=new WarehouseItem(); //here you forgot the object creation. 
     warehouseItem = bufRdr.readLine(); 
     records[numRows].processLine(warehouseItem); 
     numRows++; 
} 
+0

這將產生'IndexOutOfBoundsException'。 – 2013-10-27 15:19:27

+0

@nikpon是的,如果行數超過1000000,那麼它會拋出IndexOutOfBoundsException – Prabhakaran

+0

所以,你的代碼是不可預知的行爲,你甚至沒有抓住它。 – 2013-10-27 15:23:41

1

因爲您尚未將任何內容分配給記錄[numRows]。您只將記錄定義爲一組WarehouseItem對象。 在使用之前,您應該爲陣列的索引分配一個新的WarehouseItem。

records[numRows] = new WarehouseItem(); 
warehouseItem = bufRdr.readLine(); 
records[numRows].processLine(wareHouseitem); 
+0

這將產生'IndexOutOfBoundsException'。 – 2013-10-27 15:18:50

2

你沒有初始化數組,那是在你的代碼的原因NullPointerException,但如果你不能使用數組不使用它。

線的數量可能超過陣列的容量,使用List代替

List<WarehouseItem> records = new ArrayList<>(); 

String line = bufRdr.readLine(); 
while (line != null) { 
    WarehauseItem warehauseItem = new WarehauseItem(); 
    records.add(warehauseItem); 
    warehauseItem.processLine(line); 
    line = bufRdr.readLine(); 
} 
numRows = records.size(); 
+0

不,他只是沒有創建個人'WarehouseItem's。 – Kevin

+0

但這仍然是一個有效的觀點。 –

+0

@Kevin如果調用'processLine',如何不創建? – 2013-10-27 15:02:08