简体   繁体   中英

A NumberFormatException error when reading from CSV file

I have the following csv file:

No_Reduction    No_Reduction    No_Reduction    No_Reduction
1               15              1               9
0               7               0               0
3               1               5               1

I would like to read the file and calculate the sum for each line. The first line is some technique that I'm using in my project (forget about the duplication). To do so, I did the following:

BufferedReader readerBuffer = new BufferedReader(new FileReader("location"));
BufferedWriter bw = new BufferedWriter(new FileWriter("location",true));
while ((line = readerBuffer.readLine()) != null) {
    if(line.contains("Reduction")) {
        bw.write(convertCSVtoArrayList(line).get(0)); //I want to write the technique name in the new file
        bw.write("\n");
    }else if(!line.contains("NA")) {
        ArrayList<String> data_per_class = convertCSVtoArrayList(line);                 
        List<Double> doubleList = data_per_class.stream().map(Double::valueOf).collect(Collectors.toList()); //this is line 46
        double sum = this.calculateSum(doubleList);
        bw.write(sum);
        bw.write("\n");
    }
}
bw.close();

The convertCSVtoArrayList method:

public static ArrayList<String> convertCSVtoArrayList(String pathCSV) {
    ArrayList<String> result = new ArrayList<String>();

    if (pathCSV != null) {
        String[] splitData = pathCSV.split("\\s*,\\s*");
        for (int i = 0; i < splitData.length; i++) {
            if (!(splitData[i] == null) || !(splitData[i].length() == 0)) {
                result.add(splitData[i].trim());
            }
        }
    }

    return result;
}

Basically, the error is:

Exception in thread "main" java.lang.NumberFormatException: For input string: "" 1""
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
    at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    at java.lang.Double.parseDouble(Double.java:538)
    at java.lang.Double.valueOf(Double.java:502)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at MockerClass.applyForCase(MockerClass.java:46)
    at MockerClass.main(MockerClass.java:16)

Note that if I remove the first line (the one that contains No_Reduction ), the error disappears !!

How can I solve this issue?

Let's give a non-answer: such things are to be expected when you re-invent the wheel.

Meaning: CSV parsing is harder than you think. Typically your own hand-written parser works for the input data that you could think up. The second you throw valid CSV data at it from a different source, something that is slightly more complicated, your parser will break.

So: that exception tells you that this string " 1" can't be parsed as number, and as the other answers explain, that is due to wrong "parsing" of other elements.

Thus, my recommendation: in case you want to have a real CSV parser, use an existing library for that, like openCSV or apache commons CSV .

It appears that it's trying to convert your "No Reduction" line into integers, and failing. Is the code getting into your if(line.contains("Reducation")) block?

Perhaps add this just as a test

if(line.contains("Reduction") || line.trim().isEmpty()) 

Perhaps your input file has a newline at the end?

Seems your convertCSVtoArrayList is incorrect. The split parameter and condition for null and length are incorrect. I suppose to change that method to:

    public static ArrayList<String> convertCSVtoArrayList(String pathCSV) {
    ArrayList<String> result = new ArrayList<>();
    if (pathCSV != null) {
        String[] splitData = pathCSV.split("\\s+");
        for (int i = 0; i < splitData.length; i++) {
            if (splitData[i].length() != 0) {
                result.add(splitData[i].trim());
            }
        }
    }
    return result;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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