简体   繁体   English

读取Java中的CSV文件并将值存储在int数组中

[英]Reading CSV file in Java and storing the values in an int array

I have a CSV file of strings in this format: 我有以下格式的字符串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

All I want to do is read in the csv file and then store the 3rd and 4th coloumns data in integer arrays. 我要做的只是读取csv文件,然后将第3和第4列数据存储在整数数组中。

This is the code I have written: 这是我编写的代码:

    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();

I want to end up with two arrays, EMA which contains all the values from the 3rd coloumn and SMA which contains the values from the 4th coloumn. 我想以两个数组结束,EMA包含来自第三列的所有值,而SMA包含来自第四列的所有值。

I am getting a null pointer exception. 我收到一个空指针异常。 Can someone please tell me what mistake I am making? 有人可以告诉我我犯了什么错误吗?

Your file appears to use whitespace/tab as a delimiter, but you're splitting at commas. 您的文件似乎使用空格/制表符作为分隔符,但您正在使用逗号分隔。 That makes no sense to me. 这对我来说毫无意义。

You assume that the data row has a certain length without checking it. 您假定数据行具有一定的长度而不检查它。 That makes no sense to me. 这对我来说毫无意义。

This code will show you how to do it better: 这段代码将向您展示如何做得更好:

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;
    }
}

Here's the input file I used to test it: 这是我用来测试的输入文件:

# 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

Here's the output I got: 这是我得到的输出:

{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

[1] There should be a count++ inside the while loop [1] while循环内应该有一个count ++

[2] You have not defined/initialized the arrays EMA and SMA - causing the exception. [2]您尚未定义/初始化EMA和SMA数组-导致异常。

[3] If you split() by comma and have a space separated file, the result will be an array of unity length, and indices 2 and 3 with generate NullPointerException - even if you initialize the arrays properly. [3]如果用逗号split()并有一个空格分隔的文件,则结果将是一个单位长度的数组,并且索引2和3带有generate NullPointerException-即使您正确初始化了数组。

I suggest reading in the number by adding them to a List (like ArrayList or Vector) in the loop, since you do not know the size in advance. 我建议通过将它们添加到循环中的列表(如ArrayList或Vector)中来读取数字,因为您事先不知道大小。 Once you get out of the loop, create 2 arrays of appropriate size and copyInto() the data in the arrays. 一旦退出循环,请创建2个适当大小的数组,然后将它们复制到数组中的数据。 Let the garbage collector deal with the Vectors. 让垃圾收集器处理向量。

The problem with your code is that int[] EMA is not an initialization. 您的代码的问题是int [] EMA不是初始化。 It just defines that EMA is an array of integers, without effectively creating it (you only have the reference). 它只是将EMA定义为整数数组,而没有有效地创建它(您只有引用)。

My advice would be changing EMA and SMA to ArrayLists and instead of using attributions, you could add the current elements to the lists. 我的建议是将EMA和SMA更改为ArrayLists ,而不是使用归因,您可以将当前元素添加到列表中。

In the end of the loop, you get the number of elements at each ArrayList using the size() method and can change them into arrays using toArray method, fulfilling whichever goal you might have. 在循环的最后,您可以使用size()方法获取每个ArrayList上的元素数量,并可以使用toArray方法将它们更改为数组,从而实现您可能达到的任何目标。

Of course, I am assuming that you forgot the commas at your example. 当然,我假设您在示例中忘记了逗号。 Otherwise, you should change the delimiter to whitespace. 否则,应将定界符更改为空格。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM