从CSV文件中读取并创建对象

huangapple go评论75阅读模式
英文:

Reading from CSV file and create object

问题

我是一个对Java完全初学者,我被分配了一个练习,其中我必须从CSV文件中读取数据,然后在程序读取文件的同时为每一行数据创建一个对象。

这是CSV文件的一部分:

1,Jay, Walker,91 Boland Drive,BAGOTVILLE,NSW,2477
2,Mel, Lowe,45 Ocean Drive,MILLERS POINT,NSW,2000
3,Hugh, Manatee,32 Edgecliff Road,REDFERN,NSW,2016
4,Elizabeth, Turner,93 Webb Road,MOUNT HUTTON,NSW,2290

等等...

以下是从CSV文件中读取数据的代码:

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

public class Client_19918424 {

    public static void main(String[] args) throws FileNotFoundException {
        File inFile = new File("clients.txt");
        Scanner inputFile = new Scanner(inFile);
        String str;
        String[] tokens;
        while (inputFile.hasNext()) {
            str = inputFile.nextLine();         // 从文件中读取一行文本
            tokens = str.split(",");            // 使用逗号作为分隔符拆分行
            
            System.out.println("Client ID: " + tokens[0]);
            System.out.println("Client First Name: " + tokens[1]);
            System.out.println("Client Sur Name: " + tokens[2]);
            System.out.println("Street Address: " + tokens[3]);
            System.out.println("Suburb: " + tokens[4]);
            System.out.println("State: " + tokens[5]);
            System.out.println("Postcode:" + tokens[6]);
            System.out.println();
                
        } // 结束循环
    }
}

这是我的Client类(具有构造函数):

public class Client {
    private int clientID;
    private String firstName;
    private String surName;
    private String street;
    private String suburb;
    private String state;
    private int postcode;
    
    // 构造函数
    public Client(int ID, String fName, String sName, String str, String sb, String sta, int pCode) {
        
        clientID = ID;
        firstName = fName;
        surName = sName;
        street = str;
        suburb = sb;
        state = sta;
        postcode = pCode;
    }
}

然而,我不知道如何在程序从文件中读取数据的同时为每一行文本创建一个Client对象。
就像对于第一行,创建类似于这样的内容:

Client client1 = new Client(1, "Jay", "Walker", "91 Boland Drive", "BAGOTVILLE", "NSW", 2477);

然后将其添加到数组中:

Client[0] = client1;

有人可以帮助我解决这个问题吗?我真的很感激。

英文:

I'm a complete beginner to Java and I have been given an exercise where I have to read data from a CSV file and then create an object for each line of the file as the program reads the data from the file.

Here is part of the CSV file:

<!-- language: lang-none -->
1,Jay, Walker,91 Boland Drive,BAGOTVILLE,NSW,2477
2,Mel, Lowe,45 Ocean Drive,MILLERS POINT,NSW,2000
3,Hugh, Manatee,32 Edgecliff Road,REDFERN,NSW,2016
4,Elizabeth, Turner,93 Webb Road,MOUNT HUTTON,NSW,2290

and so on ...

Here is my code that reads data from the CSV file:

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

public class Client_19918424 {

	public static void main(String[] args) throws FileNotFoundException {
		File inFile = new File(&quot;clients.txt&quot;);
		Scanner inputFile = new Scanner(inFile);
		String str;
		String[] tokens;
		while (inputFile.hasNext()) {
			str = inputFile.nextLine();         // read a line of text from the file 
			tokens = str.split(&quot;,&quot;);            // split the line using commas as delimiter
			
			System.out.println(&quot;Client ID: &quot; + tokens[0]);
			System.out.println(&quot;Client First Name: &quot; + tokens[1]);
			System.out.println(&quot;Client Sur Name: &quot; + tokens[2]);
			System.out.println(&quot;Street Address: &quot; + tokens[3]);
			System.out.println(&quot;Suburb: &quot; + tokens[4]);
			System.out.println(&quot;State: &quot; + tokens[5]);
			System.out.println(&quot;Postcode:&quot; + tokens[6]);
			System.out.println( );
				
		} // end while
	}
}

this is my Client class (have constructor):

public class Client {
	private int clientID;
	private String firstName;
	private String surName;
	private String street;
	private String suburb;
	private String state;
	private int postcode;
	
	// constructor
	public Client (int ID, String fName, String sName, String str, String sb, String sta, int pCode) {
		
		clientID = ID;
		firstName = fName;
		surName = sName;
		street = str;
		suburb = sb;
		state = sta;
		postcode = pCode;
	}

However I don't know how to create a Client object for each line of text file as the program reads data from file.
like for the first line make something like this:

Client client1 = new Client(1, &quot;Jay&quot;, &quot;Walker&quot;, &quot;91 Boland Drive&quot;, &quot;BAGOTVILLE&quot;, &quot;NSW&quot;, 2477);

And then add it to array:

Client[0] = client1;

can someone help me to solve this question, im really appreciate.

答案1

得分: 0

你已经接近成功了。
剩下的任务是将已经打印出的每个标记映射到 Client 类中相应的字段。由于 token[0] 实际上并没有说明它持有什么值,你可以通过三种方式来实现:

while (inputFile.hasNext()) {
    str = inputFile.nextLine();
    tokens = str.split(",");
    // 由于 tokens[0] 是 String 类型,但 clientID 是 int 类型,
    // 我们需要解析它并获取整数表示。
    int clientID = Integer.parseInt(tokens[0]);
    // 都是 String 类型,无需解析。
    String firstName = tokens[1];
    String surName = tokens[2];
    String street = tokens[3];
    String suburb = tokens[4];
    String state = tokens[5];
    int postcode = Integer.parseInt(tokens[6]);
    // 唯一剩下的任务是创建一个 `Client` 类型的新对象
    // 并传递收集到的所有信息。
    Client client = new Client(clientID, firstName, surName, street, suburb, state, postcode);
    System.out.println(client + "\n");
}

此时,如果我们尝试打印客户端(最后一行),我们会得到类似于 com.example.demo.Client@30a3107a 的输出。这是因为我们没有说明我们希望如何显示我们的对象。为此,必须重写 Client 类中的 toString() 方法,像这样:

@Override
public String toString() {
    return "Client ID: " + clientID + "\n" + "Client First Name: " + firstName + "\n" 
           + "Client Sur Name: " + surName + "\n" + "Street Address: " + street + "\n" 
           + "Suburb: " + suburb + "\n" + "State: " + state + "\n" + "Postcode: " + postcode;
}

它将产生与你示例中完全相同的输出。

还可以直接通过传递这些标记来创建类,而无需创建临时变量:

Client client = new Client(Integer.parseInt(tokens[0]), tokens[1], tokens[2], tokens[3], tokens[4], tokens[5], Integer.parseInt(tokens[6]));

这种情况将我们带到使用设置器和获取器的第三种解决方案。已经定义了描述 Client 的变量,可以将它们传递以组装完美的对象,但无法检索它们。我们可以不直接在构造函数中设置变量,而是可以创建一个特殊的方法来完成这项工作,例如:

// 其他字段被省略
private int clientID;

// 以备以后使用的空构造函数,
// 因为现在,我们不能在未指定每个属性的情况下创建对象。
public Client() {
}

// 此方法与之前所做的完全相同,只是直接在构造函数中完成
public void setClientID(int clientID) {
    this.clientID = clientID;
}

// 此方法将帮助检索上述设置的数据。
public int getClientID() {
    return clientID;
}

然后 while 循环将变成这样:

Client client = new Client();
client.setClientID(Integer.parseInt(tokens[0]));
client.setFirstName(tokens[1]);
client.setSurName(tokens[2]);
client.setStreet(tokens[3]);
client.setSuburb(tokens[4]);
client.setState(tokens[5]);
client.setPostcode(Integer.parseInt(tokens[6]));

要获取这些值:

System.out.println("Client ID: " + client.getClientID());

或者,如果创建客户端时只允许包含所有字段,则可以使用带有字段的构造函数,向类中添加 getter,省略 setter 和空构造函数。

英文:

You are almost there.
All that's left to do is to map each token that is already printed to the corresponding fields in the Client class. Since token[0] doesn't really tell what value it holds you could do it in three ways:

 while (inputFile.hasNext()) {
    str = inputFile.nextLine();        
    tokens = str.split(&quot;,&quot;);           
    // Because tokens[0] is of type String but clientID is of type int,
    // we need to parse it and get the integer representation.
    int clientID = Integer.parseInt(tokens[0]);
    // Both of type String, no parsing required.
    String firstName = tokens[1];
    String surName = tokens[2];
    String street = tokens[3];
    String suburb = tokens[4];
    String state = tokens[5];
    int postcode = Integer.parseInt(tokens[6]);
    // Then all that&#39;s left to do is to create a new object of `Client` type
    // and pass all the gathered information.
    Client client = new Client(clientID, firstName, surName, street, suburb, state, postcode);
    System.out.println(client + &quot;\n&quot;);
}

At this moment if we try to print the client (last line) we will get something like this: com.example.demo.Client@30a3107a. That's because we didn't tell how we want our object to be displayed. For that toString() method in Client class has to be overriden like so:

@Override
public String toString() {
    return &quot;Client ID: &quot; + clientID + &quot;\n&quot; + &quot;Client First Name: &quot; + firstName + &quot;\n&quot; 
           + &quot;Client Sur Name: &quot; + surName + &quot;\n&quot; + &quot;Street Address: &quot; + street + &quot;\n&quot; 
           + &quot;Suburb: &quot; + suburb + &quot;\n&quot; + &quot;State: &quot; + state + &quot;\n&quot; + &quot;Postcode: &quot; + postcode;
}  

It will give the exact output that is in your example.

It is achievable to create the class by passing those tokens directly as well, without the creation of temporary variables:

Client client = new Client(Integer.parseInt(tokens[0]), tokens[1], tokens[2], tokens[3], tokens[4], tokens[5], Integer.parseInt(tokens[6]));

This case brings us to the third solution with setters and getters.
The variables that describe the Client are already defined, it is possible to pass them to assemble the perfect object, but it is not possible to retrieve them. Instead of setting the variables directly in the constructor, we can create a special method that will do the job, for instance:

// Other fields omitted
private int clientID;

// The empty constructor required for later usage,
// since right now, we can&#39;t create the object without specifying every property.
public Client() {
}

// This method does exactly the same thing that was done before but
// in the constructor directly
public void setClientID(int clientID) {
    this.clientID = clientID;
}

// This method will assist in retrieving the set data from above.
public int getClientID() {
    return clientID;
}

And then the while loop would look like this instead:

Client client = new Client();
client.setClientID(Integer.parseInt(tokens[0]));
client.setFirstName(tokens[1]);
client.setSurName(tokens[2]);
client.setStreet(tokens[3]);
client.setSuburb(tokens[4]);
client.setState(tokens[5]);
client.setPostcode(Integer.parseInt(tokens[6]));

And to get those values:

System.out.println(&quot;Client ID: &quot; + client.getClientID());

Or you could use the constructor with the fields to create the client, add getters in the class, omit both setters, and the empty constructor if the creation of the client should only be possible with all the fields present.

huangapple
  • 本文由 发表于 2020年10月23日 02:42:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/64488594.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定