0

この形式の文字列のCSVファイルがあります。

14/10/2011  422     391.6592    394.52324   0.039215686
13/10/2011  408.43  391.7612    395.0686031 0.039215686
12/10/2011  402.19  391.834     395.3478736 0.039215686

私がやりたいのは、csvファイルを読み込んでから、3番目と4番目の列のデータを整数配列に格納することだけです。

これは私が書いたコードです:

    BufferedReader CSVFile = 
            new BufferedReader(new FileReader("appleData.csv"));

    String dataRow = CSVFile.readLine(); 
    int count = 0;

    while (dataRow != null){
        String[] dataArray = dataRow.split(",");

        EMA[count] = dataArray[2];
        SMA[count] = dataArray[3];

        dataRow = CSVFile.readLine(); // Read next line of data.
    }
    // Close the file once all data has been read.
    CSVFile.close();

最終的に、3番目の列のすべての値を含むEMAと4番目の列の値を含むSMAの2つの配列を作成します。

nullポインタ例外が発生します。誰かが私が犯している間違いを教えてもらえますか?

4

3 に答える 3

4

ファイルは区切り文字として空白/タブを使用しているように見えますが、カンマで分割しています。それは私には意味がありません。

データ行はチェックせずに一定の長さであると想定します。それは私には意味がありません。

このコードは、それをより良くする方法を示します:

package cruft;

import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * CsvParser
 * @author Michael
 * @link http://stackoverflow.com/questions/14114358/reading-csv-file-in-java-and-storing-the-values-in-an-int-array/14114365#14114365
 * @since 1/1/13 4:26 PM
 */
public class CsvParser {
    public static void main(String[] args) {
        try {
            FileReader fr = new FileReader((args.length > 0) ? args[0] : "resources/test.csv");
            Map<String, List<String>> values = parseCsv(fr, "\\s+", true);
            System.out.println(values);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Map<String, List<String>> parseCsv(Reader reader, String separator, boolean hasHeader) throws IOException {
        Map<String, List<String>> values = new LinkedHashMap<String, List<String>>();
        List<String> columnNames = new LinkedList<String>();
        BufferedReader br = null;
        br = new BufferedReader(reader);
        String line;
        int numLines = 0;
        while ((line = br.readLine()) != null) {
            if (StringUtils.isNotBlank(line)) {
                if (!line.startsWith("#")) {
                    String[] tokens = line.split(separator);
                    if (tokens != null) {
                        for (int i = 0; i < tokens.length; ++i) {
                            if (numLines == 0) {
                                columnNames.add(hasHeader ? tokens[i] : ("row_"+i));
                            } else {
                                List<String> column = values.get(columnNames.get(i));
                                if (column == null) {
                                    column = new LinkedList<String>();
                                }
                                column.add(tokens[i]);
                                values.put(columnNames.get(i), column);
                            }
                        }
                    }
                    ++numLines;
                }
            }
        }
        return values;
    }
}

これが私がそれをテストするために使用した入力ファイルです:

# This shows that comments, headers and blank lines work fine, too.
date        value1  value2      value3      value4
14/10/2011  422     391.6592    394.52324   0.039215686

13/10/2011  408.43  391.7612    395.0686031 0.039215686



12/10/2011  402.19  391.834     395.3478736 0.039215686

これが私が得た出力です:

{date=[14/10/2011, 13/10/2011, 12/10/2011], value1=[422, 408.43, 402.19], value2=[391.6592, 391.7612, 391.834], value3=[394.52324, 395.0686031, 395.3478736], value4=[0.039215686, 0.039215686, 0.039215686]}

Process finished with exit code 0
于 2013-01-01T21:24:56.893 に答える
0

[1] while ループ内に count++ が必要です

[2] 配列 EMA および SMA を定義/初期化していないため、例外が発生します。

[3] コンマで split() し、スペースで区切られたファイルがある場合、配列を適切に初期化したとしても、結果は 1 の長さの配列になり、インデックス 2 と 3 は NullPointerException を生成します。

事前にサイズがわからないため、ループ内のリスト (ArrayList や Vector など) に追加して数値を読み取ることをお勧めします。ループから抜けたら、適切なサイズの 2 つの配列を作成し、配列内のデータを copyInto() します。ガベージ コレクターにベクトルを処理させます。

于 2013-01-01T21:30:26.053 に答える
0

コードの問題は、 int[] EMA が初期化ではないことです。EMA が整数の配列であることを定義するだけで、効果的に作成することはありません (参照しかありません)。

私のアドバイスは、EMA と SMA をArrayListsに変更し、属性を使用する代わりに、現在の要素をリストに追加することです。

ループの最後で、size() メソッドを使用して各 ArrayList の要素数を取得し、toArray メソッドを使用してそれらを配列に変更し、目標を達成します。

もちろん、あなたの例でカンマを忘れたと思います。それ以外の場合は、区切り文字を空白に変更する必要があります。

于 2013-01-01T21:44:19.563 に答える