Sean2148
Sean2148

Reputation: 365

How to use CSV values as constructor paramaters in Java 8

I am reading from a CSV file, and using the values from the file to create an object for every line in the file. However, I got the error "InputMismatchException", which I discovered is happening because the compiler is expecting a String, because the values in the CSV are not separated by white space (well the commas are being read as part of the line).

However scanner doesn't have a replace method to create any spaces so would I be correct in assuming I must convert the lines in the file to a String? That would seem like the only other way to split the lines up into values. Although then all the values would be Strings so they would not be suitable for the constructor parameters expecting ints/doubles. If any of this is confusing please let me know as I find it hard to explain what I'm having trouble with.

Here is my code:

package code;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Element {
    public int number;
    public String symbol;
    public String name;
    public int group;
    public int period;
    public double weight;

    public Element(int number, String symbol, String name, int group, int period, double weight){

        this.number = number;
        this.symbol = symbol;
        this.name = name;
        this.group = group;
        this.period = period;
        this.weight = weight;
    }

    public String toString(){
        return number + ", " + symbol + ", " + name + ", " + group + ", " + period + ", " + weight;
    }
    public static List<Element> readElements() throws FileNotFoundException{
        Scanner reader = new Scanner(new File("C:\\Users\\Sean\\Desktop\\elements.csv"));
        List<Element> list= new ArrayList<Element>();
        reader.nextLine();

        while (reader.hasNextLine()){
            Element e = new Element(reader.nextInt(), reader.next(), reader.next(), reader.nextInt(), reader.nextInt(), reader.nextDouble());
            list.add(e);
        }
        return list;
    }
}

CSV File

Atomic Number,Symbol,Name,Group,Period,Atomic Weight
23,V,Vanadium,5,4,50.9415
54,Xe,Xenon,18,5,131.293
70,Yb,Ytterbium,3,6,173.045

So I'm trying to take the values from the CSV file, e.g. "23" would be the first int, and use it to create an object in the while loop using scanner.nextInt.

Upvotes: 2

Views: 1381

Answers (1)

Ousmane D.
Ousmane D.

Reputation: 56453

You can utilise the useDelimiter method like so:

Scanner reader = new Scanner(new File("C:\\Users\\Sean\\Desktop\\elements.csv"))
                      .useDelimiter(",");

Alternatively, you can also read the data like this:

try (Scanner reader = new Scanner(new File("C:\\Users\\Sean\\Desktop\\elements.csv"))) {
        reader.nextLine();
        while (reader.hasNextLine()){
                String[] tempArray = reader.nextLine().split(",");
                Element e = new Element(Integer.parseInt(tempArray[0]), 
                                        tempArray[1], 
                                        tempArray[2],
                                        Integer.parseInt(tempArray[3]),
                                        Integer.parseInt(tempArray[4]),
                                        Double.parseDouble(tempArray[5]));
                list.add(e);
        }

} catch (IOException e) {
       e.printStackTrace();
}

or if you're into Java-8 streams then another solution could be:

List<Element> list = new ArrayList<>();
try (Stream<String> stream = Files.lines(Paths.get("C:\\Users\\Sean\\Desktop\\elements.csv"))) {

     list = stream.skip(1)
                  .map(line -> {
                      String[] tempArray = line.split(",");
                      Element e = new Element(Integer.parseInt(tempArray[0]),
                              tempArray[1],
                              tempArray[2],
                              Integer.parseInt(tempArray[3]),
                              Integer.parseInt(tempArray[4]),
                              Double.parseDouble(tempArray[5]));
                      return e;
                    }).collect(Collectors.toCollection(ArrayList::new));

} catch (IOException e) {
    e.printStackTrace();
}

Upvotes: 2

Related Questions