从CSV文件初始化对象数组

时间:2021-12-02 01:22:55

This problem takes a bit of explaining, I'll try to be as concise as possible:

这个问题需要一些解释,我会尽量简洁:

I have am trying to initalise an array of Can objects, these objects only have 2 fields (both Strings): name, manufacturer

我正在尝试初始化Can对象的数组,这些对象只有2个字段(两个字符串):名称,制造商

I am trying to initialise the fields by reading from a CSV file with the following format:

我试图通过使用以下格式从CSV文件读取来初始化字段:

Tomatoes,Heinz

Legumes,Jerry

(no space between the lines, it's being formatted like that on this site for some reason)

(行之间没有空格,由于某种原因,它的格式就像在这个网站上那样)

The first string in each row is the value I want to be the name, the 2nd is the manufacturer.

每行中的第一个字符串是我想要的名称值,第二个是制造商。

So I've created a method to read each line of the CSV, which passes each line to a tokenizer method to extract single values:

所以我创建了一个方法来读取CSV的每一行,它将每行传递给tokenizer方法以提取单个值:

private void readFile (String inFilename) {
    FileInputStream fileStrm = null;
    InputStreamReader rdr;
    BufferedReader bufRdr;
    int lineNum;
    String line;
        try {
            fileStrm = new FileInputStream(inFilename);
            rdr = new InputStreamReader(fileStrm);
            bufRdr = new BufferedReader(rdr);
            lineNum = 0;
            line = bufRdr.readLine();
            while {line != null) {
                lineNum++;
                processLine(line);  //passes line to tokenizer
                line = bufRdr.readLine();
                 }
            fileStrm.close();
        }
        catch (IOException e) {
            if (fileStrm != null) {
                try { fileStrm.close(); } catch (IOException ex2) { }
             }
             System.out.println("Error in file processing: " + e.getMessage());
        }   
    }

The lines are passed to this tokenizer method:

这些行传递给此tokenizer方法:

private String processLine(String csvRow) {
    String thisToken = null;
    StringTokenizer strTok;
    strTok = new StringTokenizer(csvRow, ",");
        while (strTok.hasMoreTokens()) {
            thisToken = strTok.nextToken();
        }
}

And that's where I get a bit stuck. To initialise my array I think I'd need a for loop, something like

这就是我有点卡住的地方。为了初始化我的数组,我想我需要一个for循环,比如

for (int i=0; i<=array.length;i++)
    {
    array[i].name = readFile("filename.csv");
    array[i].manufacturer = readFile("filename.csv");
    }

But obviously this will not work. Can anyone suggest how I can go about this? I'd prefer to keep the code mostly intact and figure out a solution using the existing code.

但显然这不起作用。谁能建议我怎么做呢?我宁愿保持代码大部分完整,并使用现有代码找出解决方案。

Thanks

1 个解决方案

#1


0  

First thing: -

第一件事: -

You are calling processLine(line);, but are not returning the token read from this method.. So, the token obtained in this method in engulped there only.. So, you should return something from that method..

你正在调用processLine(line);,但是没有返回从这个方法中读取的令牌。所以,在这个方法中获得的令牌只是在那里进行的..所以,你应该从该方法返回一些东西..

Second:-

array[i].name = readFile("filename.csv");
array[i].manufacturer = readFile("filename.csv");

In the above code, you are calling readFile() each time for the two attributes.. So, even if you return somthing, these two attributes will be initialized to same value.. Because each time you are starting reading file from scratch..

在上面的代码中,每次都为两个属性调用readFile()。所以,即使你返回somthing,这两个属性也会被初始化为相同的值。因为每次你从头开始读取文件..

Third thing: -

第三件事: -

In fact your above code will not compile.. Because you are assigning the value of readFile() (which is actually not returning anything) to array.. So give a return type to this method.. It would be String.. And returning the tokens read..

实际上你的上面的代码不会编译..因为你将readFile()的值(实际上没有返回任何东西)分配给数组..所以给这个方法一个返回类型..它将是String ..并返回令牌阅读..

EDIT: - * I would suggest, you can use split() method of String class.. Tokenizer is not needed here, for justsplittingaround a singlecomma(,)`

编辑: - *我建议,你可以使用String类的split()方法。这里不需要Tokenizer,只需要分配一个singlecomma(,)`

Also, rather than using an array, you can use ArrayList, in which you can add your newly created object on the fly.. That way, you will not have to fix the size of array.. (And this is what you will want, as you don't know how much line you will have in your file right?)

此外,您可以使用ArrayList,而不是使用数组,您可以在其中动态添加新创建的对象。这样,您就不必修复数组的大小..(这就是您想要的,因为你不知道你的文件中有多少行?)

Here's what you can do: -

这是你能做的: -

  • Call the method readFile from somewhere, probably main()

    从某个地方调用readFile方法,可能是main()

    readFile("filename.csv")
    
  • In your readFile() method, you can iterate over file to create an ArrayList like this: -

    在readFile()方法中,您可以迭代文件以创建一个这样的ArrayList: -

    List<Can> yourList = new ArrayList<>();
    while ((line = reader.readLine()) != null) {
    
        String[] wordRead = line.split(',');
        yourList.add(new Can(wordRead[0], wordRead[1]));
    }
    

I assume, Can is the name of your class as you stated in your problem..

我假设,你的课程名称就像你在问题中所说的那样。

#1


0  

First thing: -

第一件事: -

You are calling processLine(line);, but are not returning the token read from this method.. So, the token obtained in this method in engulped there only.. So, you should return something from that method..

你正在调用processLine(line);,但是没有返回从这个方法中读取的令牌。所以,在这个方法中获得的令牌只是在那里进行的..所以,你应该从该方法返回一些东西..

Second:-

array[i].name = readFile("filename.csv");
array[i].manufacturer = readFile("filename.csv");

In the above code, you are calling readFile() each time for the two attributes.. So, even if you return somthing, these two attributes will be initialized to same value.. Because each time you are starting reading file from scratch..

在上面的代码中,每次都为两个属性调用readFile()。所以,即使你返回somthing,这两个属性也会被初始化为相同的值。因为每次你从头开始读取文件..

Third thing: -

第三件事: -

In fact your above code will not compile.. Because you are assigning the value of readFile() (which is actually not returning anything) to array.. So give a return type to this method.. It would be String.. And returning the tokens read..

实际上你的上面的代码不会编译..因为你将readFile()的值(实际上没有返回任何东西)分配给数组..所以给这个方法一个返回类型..它将是String ..并返回令牌阅读..

EDIT: - * I would suggest, you can use split() method of String class.. Tokenizer is not needed here, for justsplittingaround a singlecomma(,)`

编辑: - *我建议,你可以使用String类的split()方法。这里不需要Tokenizer,只需要分配一个singlecomma(,)`

Also, rather than using an array, you can use ArrayList, in which you can add your newly created object on the fly.. That way, you will not have to fix the size of array.. (And this is what you will want, as you don't know how much line you will have in your file right?)

此外,您可以使用ArrayList,而不是使用数组,您可以在其中动态添加新创建的对象。这样,您就不必修复数组的大小..(这就是您想要的,因为你不知道你的文件中有多少行?)

Here's what you can do: -

这是你能做的: -

  • Call the method readFile from somewhere, probably main()

    从某个地方调用readFile方法,可能是main()

    readFile("filename.csv")
    
  • In your readFile() method, you can iterate over file to create an ArrayList like this: -

    在readFile()方法中,您可以迭代文件以创建一个这样的ArrayList: -

    List<Can> yourList = new ArrayList<>();
    while ((line = reader.readLine()) != null) {
    
        String[] wordRead = line.split(',');
        yourList.add(new Can(wordRead[0], wordRead[1]));
    }
    

I assume, Can is the name of your class as you stated in your problem..

我假设,你的课程名称就像你在问题中所说的那样。