Java 如何从CSV字符串文件创建具有字符串的对象数组?

Java 如何从CSV字符串文件创建具有字符串的对象数组?,java,arrays,class,object,csv,Java,Arrays,Class,Object,Csv,我有一些从csv文件中读取的代码,该文件中充满了很多人的姓、名和出生年份。在csv文件中看起来如下所示: nameLast nameFirst birthYear Santos Valerio 1972 Tekulve Kent 1947 Valentine Fred 1935 我有一个类叫做Human,Human类也有这三个值。我想创建一个human类数组,并将csv文件中的所有数据传递给它。这样,如果[0]处数

我有一些从csv文件中读取的代码,该文件中充满了很多人的姓、名和出生年份。在csv文件中看起来如下所示:

nameLast    nameFirst   birthYear
Santos      Valerio       1972
Tekulve      Kent         1947
Valentine    Fred         1935
我有一个类叫做Human,Human类也有这三个值。我想创建一个human类数组,并将csv文件中的所有数据传递给它。这样,如果[0]处数组的第一个实例中有三个值,两个值表示名称,一个值表示年份。以下是我目前掌握的代码:

package testing.csv.files;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Human {

    String lastName;
    String firstName;
    String birthYear;

    public static void main(String[] args) {
        //.csv comma separated values
        String fileName = "C:/Users/Owner/Desktop/Data.csv";
        File file = new File(fileName); // TODO: read about File Names
        try {
            Scanner inputStream = new Scanner(file);
            inputStream.next(); //Ignore first line of titles
            while (inputStream.hasNext()){
                String data = inputStream.next(); // gets a whole line
                String[] values = data.split(",");
                System.out.println(values[2]);
            }
            inputStream.close();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
我这里的内容将打印出所有的出生年份,因为值[2]是出生年份。我想我可以改变路线

   String[] values = data.split(",");
阅读

   Human[] values = data.split(",");
然后它会自动将值lastName、firstName和birthyear分配到数组中每个对象的正确位置。但是,这样做只会产生错误消息

   incompatible types: String[] cannot be converted to Human[]
我还试着把这一行上面的

  String data = inputStream.next(); // gets a whole line

但是我收到了同样的错误信息


那么我做错了什么?也许我没有像我认为的那样正确地定义类,或者我的方法是否有更大的错误?请告诉我您的想法。

类字符串中的方法
split
返回字符串数组,而不是
人的数组。要创建
Human
的数组,需要将从
split
返回的字符串数组解析为Human需要的值

class Human{
    String firstName;
    String lastName;
    int birthYear;
    public Human(String first, String last, int birthYear){
        this.firstName = first;
        this.lastName = last;
        this.birthYear = birthYear;
    }
}
int numHumansInCSV = //How many humans are in your file?
Human[] humanArray = new Human[numHumansInCSV];
int index = 0;
while (inputStream.hasNext()){
    String data = inputStream.next(); // gets a whole line
    String[] values = data.split(",");
    String lastName = values[0];
    String firstName = values[1];
    int birthYear = Integer.parseInt(values[2]);
    Human human = new Human(firstName, lastName, birthYear);
    //put human in human array.
    humanArray[index] = human;
    index += 1;
}
如果您可以使用像
列表
这样的数据结构,那将比数组更合适,因为您可能不知道您的CSV文件包含多少人

此外,该解析代码实际上应该在它自己的类中。如果我写这篇文章,我会这么做

public class HumanCSVReader{

    public List<Human> read(String csvFile, boolean expectHeader) throws IOException{
        File file = new File(csvFile);
        Scanner scanner = new Scanner(file);
        int lineNumber = 0;
        List<Human> humans = new List<Human>();
        while(scanner.hasNextLine()){
            if(expectHeader && lineNumber==0){
                ++lineNumber;
                continue;
            }

            String line = scanner.nextLine();
            String csv = line.split(",");
            if(csv.length!=3)
                throw new IOException("Bad input in "+csvFile+", line "+lineNumber);
            String firstName = list[0];
            String lastName = list[1];
            try{
                int birthYear = Integer.parseInt(list[2]);
            }catch(NumberFormatException e){
                throw new IOException("Bad birth year in "+csvFile+", line "+lineNumber);
            }
            Human human = new Human(fistName, lastName, birthYear);
            humans.add(human);
            ++lineNumber;
        }
        return humans;
    }
}
公共类HumanCSVReader{
公共列表读取(字符串csvFile,布尔expectHeader)引发IOException{
文件文件=新文件(csvFile);
扫描仪=新扫描仪(文件);
int lineNumber=0;
List humans=新列表();
while(scanner.hasNextLine()){
if(expectHeader&&lineNumber==0){
++行号;
继续;
}
字符串行=scanner.nextLine();
字符串csv=line.split(“,”);
如果(csv.length!=3)
抛出新IOException(“在“+csvFile+”,行“+lineNumber”中输入错误);
字符串firstName=list[0];
字符串lastName=list[1];
试一试{
int birthYear=Integer.parseInt(列表[2]);
}捕获(数字格式){
抛出新IOException(“在“+csvFile+”,行“+lineNumber”中出生年份不正确);
}
人类=新人类(fistName、姓氏、出生年份);
人类。添加(人类);
++行号;
}
回归人类;
}
}

只需将其加载到您的人类阵列中即可。它甚至可以处理一些基本的验证。

首先,您的人工类需要一个构造函数。插入以下方法

public Human(String[] str) {
  lastName = str[0];
  firstName = str[1];
  birthYear = str[2];
}
现在,您可以使用

Human someHuman = new Human(data.split(","));

这是一个坏主意,因为它违反了一个非常基本的面向对象原则,即关注点分离。此外,出生年份应为整数。
Human someHuman = new Human(data.split(","));