英文:
Creating objects from reading a file that also have dynamic arrays as their fields
问题
我有一个包含购买信息的文本文件,它的结构如下:
客户姓名 制表符 会员类型 制表符 购物日期 制表符 产品名称 制表符 数量 换行符
一个客户可以一次购买多个不同的物品,所以产品名称和数量可以出现多次,就像这样:
Mary gold 26.01.2020 Sweater 1 Jeans 2
Eve silver 20.02.2020 Sweater 2 Jeans 1
Steve bronze 19.01.2020 Jeans 2 Sweater 3
我目前正在尝试从这些数据中创建一个客户对象,以下是我的实现代码:
import java.io.File;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException, ParseException {
Scanner shoppingList = new Scanner(new File("shoppingList.txt"));
shoppingList.useDelimiter("[\t\n]");
Customer[] customers = new Customer[0];
while (shoppingList.hasNext()) {
String customerName = shoppingList.next();
String customerMembershipType = shoppingList.next();
String purchaseDate = shoppingList.next();
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
Date date = formatter.parse(purchaseDate);
String[] productNameList = new String[0];
int[] quantityList = new int[0];
while (shoppingList.hasNext()) {
// 这是我卡住的地方
}
Customer newCustomer = new Customer(customerName, customerMembershipType, date, productNameList, quantityList);
customers = addCustomer(customers, newCustomer);
}
}
private static Customer[] addCustomer(Customer[] customers, Customer customerToAdd) {
Customer[] newCustomers = new Customer[customers.length + 1];
System.arraycopy(customers, 0, newCustomers, 0, customers.length);
newCustomers[newCustomers.length - 1] = customerToAdd;
return newCustomers;
}
static class Customer {
protected String customerName;
protected String customerMembershipType;
protected Date purchaseDate;
protected String[] productNameList;
protected int[] quantityList;
public Customer(String customerName, String customerMembershipType, Date purchaseDate, String[] productNameList, int[] quantityList) {
this.customerName = customerName;
this.customerMembershipType = customerMembershipType;
this.purchaseDate = purchaseDate;
this.productNameList = productNameList;
this.quantityList = quantityList;
}
}
}
基本上,我想创建可以容纳产品名称列表和它们数量列表的 Customer 对象,但由于数组是不可变的,而且客户可以购买无限数量的产品类型,所以在不使用 ArrayList 的情况下很难找到解决方案。在这一点上,我该怎么办?
(注意:我已经将代码中的 HTML 实体字符进行了修复,以便于理解。)
要解决这个问题,您可以使用动态数组(ArrayList 的概念)来存储产品名称列表和数量列表,而不是使用固定大小的数组。这将允许客户购买不同数量的产品而不受限制。下面是如何修改您的代码:
import java.io.File;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException, ParseException {
Scanner shoppingList = new Scanner(new File("shoppingList.txt"));
shoppingList.useDelimiter("[\t\n]");
ArrayList<Customer> customers = new ArrayList<>();
while (shoppingList.hasNext()) {
String customerName = shoppingList.next();
String customerMembershipType = shoppingList.next();
String purchaseDate = shoppingList.next();
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
Date date = formatter.parse(purchaseDate);
ArrayList<String> productNameList = new ArrayList<>();
ArrayList<Integer> quantityList = new ArrayList<>();
while (shoppingList.hasNext()) {
String productName = shoppingList.next();
int quantity = shoppingList.nextInt();
productNameList.add(productName);
quantityList.add(quantity);
}
Customer newCustomer = new Customer(customerName, customerMembershipType, date, productNameList, quantityList);
customers.add(newCustomer);
}
}
static class Customer {
protected String customerName;
protected String customerMembershipType;
protected Date purchaseDate;
protected ArrayList<String> productNameList;
protected ArrayList<Integer> quantityList;
public Customer(String customerName, String customerMembershipType, Date purchaseDate, ArrayList<String> productNameList, ArrayList<Integer> quantityList) {
this.customerName = customerName;
this.customerMembershipType = customerMembershipType;
this.purchaseDate = purchaseDate;
this.productNameList = productNameList;
this.quantityList = quantityList;
}
}
}
现在,您可以使用 ArrayList 来存储客户的购买信息,而不受固定数组大小的限制。这个修改允许客户购买不同数量的产品类型,同时保持代码的灵活性。
英文:
I have a text file that contains purchase informations and it has a structure like this
CustomerName tab MembershipType tab ShoppingDate tab ProductName tab Quantity newline
A customer can purchase several different objects at once so ProductName and Quantity can occur more than one time like this
Mary gold 26.01.2020 Sweater 1 Jeans 2
Eve silver 20.02.2020 Sweater 2 Jeans 1
Steve bronze 19.01.2020 Jeans 2 Sweater 3
I am currently trying to create an customers object from these data here is my implementation
import java.io.File;
import java.io.FileNotFoundException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException, ParseException {
Scanner shoppingList = new Scanner(new File("shoppingList.txt");
shoppingList.useDelimiter("[\t\n]");
Customer[] customers = new Customer[0];
while (shoppingList.hasNext()) {
String customerName = shoppingList.next();
String customerMembershipType = shoppingList.next();
String purchaseDate = shoppingList.next();
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
Date date = formatter.parse(purchaseDate);
String[] productNameList = new String[0];
int[] quantityList = new int[0];
while (shoppingList.hasNext()) {
//this is where i stuck
}
Customer[] newCustomer = new Customer(customerName, customerMembershipType, purchaseDate, productNameList, quantityList);
customers = addCustomer(customers, newCustomer);
}
}
private static Customer[] addCustomer(Customer[] customers, Customer customerToAdd) {
Customer[] newCustomers = new Customer[customers.length + 1];
System.arraycopy(customers, 0, newCustomers, 0, customers.length);
newCustomers[newCustomers.length - 1] = customerToAdd;
return newCustomers;
}
static class Customer {
protected String customerName;
protected String customerMembershipType;
protected Date purchaseDate;
protected String[] productNameList;
protected int[] quantityList;
public Customer(String customerName, String customerMembershipType, Date purchaseDate, String[] productNameList, int[] quantityList) {
this.customerName = customerName;
this.customerMembershipType = customerMembershipType;
this.purchaseDate = purchaseDate;
this.productNameList = productNameList;
this.quantityList = quantityList;
}
}
Basically I want to create Customer objects that can hold product name lists and their quanitites' list but since arrays are immutable and Customers can have purchase unlimited amount of product type I cant find a solution without using arrayLists however i cant use it in this assignment. What can I do at this point?
答案1
得分: 1
我建议,与其尝试读取顾客行并解析这些行,你可以分开进行,即按行读取,每行代表一个顾客,然后根据你的逻辑解析这些行。
类似以下方式(注意,我更改了顾客的表示方式,以及现在顾客是一个List而不是一个数组):
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException, ParseException {
BufferedReader reader = new BufferedReader(new FileReader(new File("shoppingList.txt")));
List<Customer> customers = new ArrayList<>();
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
Scanner shoppingList = new Scanner(line);
String customerName = shoppingList.next();
String customerMembershipType = shoppingList.next();
String purchaseDate = shoppingList.next();
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
Date date = formatter.parse(purchaseDate);
Customer customer = new Customer(customerName, customerMembershipType, date);
while (shoppingList.hasNext()) {
customer.addProduct(shoppingList.next(), shoppingList.nextInt());
}
customers.add(customer); // 将顾客添加到顾客列表中
}
}
static class Customer {
protected String customerName;
protected String customerMembershipType;
protected Date purchaseDate;
protected Map<String, Integer> products = new HashMap<>();
public Customer(String customerName, String customerMembershipType, Date purchaseDate) {
this.customerName = customerName;
this.customerMembershipType = customerMembershipType;
this.purchaseDate = purchaseDate;
}
public void addProduct(String name, int qty) {
products.put(name, qty);
}
}
}
如果你有任何其他问题,请随时提出。
英文:
I suggest instead of trying to read lines of customers AND parsing those lines, you do it separately, i.e. read lines as lines, with line per customer, and then parse lines according to your logic.
Something like the below (note I changed the Customer representation, as well as customers are now List instead of an array):
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException, ParseException {
BufferedReader reader = new BufferedReader(new FileReader(new File("shoppingList.txt")));
List<Customer> customers = new ArrayList<>();
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
Scanner shoppingList = new Scanner(line);
String customerName = shoppingList.next();
String customerMembershipType = shoppingList.next();
String purchaseDate = shoppingList.next();
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
Date date = formatter.parse(purchaseDate);
Customer customer = new Customer(customerName, customerMembershipType, date);
while (shoppingList.hasNext()) {
customer.addProduct(shoppingList.next(), shoppingList.nextInt());
}
}
}
static class Customer {
protected String customerName;
protected String customerMembershipType;
protected Date purchaseDate;
protected Map<String, Integer> products = new HashMap<>();
public Customer(String customerName, String customerMembershipType, Date purchaseDate) {
this.customerName = customerName;
this.customerMembershipType = customerMembershipType;
this.purchaseDate = purchaseDate;
}
public void addProduct(String name, int qty) {
products.put(name, qty);
}
}
}
答案2
得分: 0
我能想到的最简单解决方案是:当旧数组已满时,创建一个尺寸更大的新数组(假设是旧数组大小的两倍),然后将元素复制到新数组中。
英文:
Simplest solution I can think of is to: create a new array with bigger size (Let's say double the size of old one) when the older one is full and then copy the elements to the new array.
答案3
得分: 0
逐项阅读信息存在两个问题:首先,你不知道购物清单包含多少物品,正如你所发现的,更糟糕的是:你不知道购物清单在哪里结束,新客户的数据从哪里开始。
因此,我会逐行读取文件,并按分隔符分割行。
while (shoppingList.hasNextLine()) {
String line = shoppingList.nextLine();
String[] lineItems = line.split("\t");
String customerName = lineItems[0];
String customerMembershipType = lineItems[1];
String purchaseDate = lineItems[2];
// 其他处理
现在,你知道在这前面的三个项之后,其余的项是产品名称和数量。你可以使用 `lineItems` 的大小来计算有多少个产品:
```java
int productCount = (lineItems.length - 3)/2;
String[] productNameList = new String[productCount];
int[] quantityList = new int[productCount];
将这些值添加到这些数组中现在变得很简单,只需使用循环:
int itemIndex = 3;
for (int i = 0; i < productCount; i++) {
productNameList[i] = lineItems[itemIndex];
itemIndex = itemIndex + 1; // 前进到行中的下一项
quantityList[i] = Integer.parseInt(lineItems[itemIndex]);
itemIndex = itemIndex + 1; // 前进到行中的下一项
}
英文:
Reading information item by item like this has two problems: you don't know how many things the shopping list contains like you've discovered, but worse: you don't know where the shopping list ends and the data for a new customer begins.
So what I would do is read the file line by line, and split the line by the separator.
while (shoppingList.hasNextLine()) {
String line = shoppingList.nextLine();
String[] lineItems = line.split("\t");
String customerName = lineItems[0];
String customerMembershipType = lineItems[1];
String purchaseDate = lineItems[2];
// and so on
Now, you know that after these first 3 items the rest of the items are product names and quantities. You can calculate how many products there are using the size of lineItems
:
int productCount = (lineItems.length - 3)/2;
String[] productNameList = new String[productCount];
int[] quantityList = new int[productCount];
Adding the values into these arrays is now simple for loop:
int itemIndex = 3;
for (int i = 0; i < productCount; i++) {
productNameList[i] = lineItems[itemIndex];
itemIndex = itemIndex + 1; // advance to next item in the line
quantityList[i] = Integer.parseInt(lineItems[itemIndex]);
itemIndex = itemIndex + 1; // advance to next item in the line
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论