Java 从文本文件中读取数据并创建对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30564462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read data from a text file and create an object
提问by frl93
I need some help: I'm making a Supermarket simulation on Java, but I've got one problem, I have a text file (Stock.txt) where I have all the supermarket stock on it for example:
我需要一些帮助:我正在使用 Java 进行超市模拟,但我遇到了一个问题,我有一个文本文件 (Stock.txt),其中包含所有超市库存,例如:
- 0-Bakery-Chocolate Cake-$12.5-250
- 1-Meat-Premium Steak-$2.6-120
- 2-Seafood-Tuna - $1.2-14
- ...
- 0-面包店-巧克力蛋糕-$12.5-250
- 1-Meat-Premium Steak-$2.6-120
- 2-海鲜-金枪鱼 - 1.2-14 美元
- ...
Where the first number is the "id" for the product, next is the department the product belongs, third is the name of the product, the next thing is the price, and the last number is how much pieces of the product the stock has. I have this class:
其中第一个数字是产品的“id”,其次是产品所属的部门,第三个是产品名称,接下来是价格,最后一个数字是该产品的库存数量. 我有这门课:
public class Product {
protected String name;
protected double price;
protected String department;
protected int id;
protected int stock;
}
So, basically what I need to do is to read each line from the text file and create the product, i.e. for the first line make something like this:
所以,基本上我需要做的是从文本文件中读取每一行并创建产品,即对于第一行做这样的事情:
Product product1 = new Product(0,"Bakery","Chocolate Cake", 12.5, 250);
And then add it to an array
然后将其添加到数组中
Product[0] = product1;
For all the things that are in the text file, then, when running the simulation each costumer will buy a random quantity of random products in stock, so the stock number will decrease. Finally, when the simulation ends, the program must write in the same text file, the modify quantity of each product.
对于文本文件中的所有内容,当运行模拟时,每个客户将购买随机数量的库存随机产品,因此库存数量将减少。最后,当模拟结束时,程序必须在同一个文本文件中写入每个产品的修改数量。
The thing is that maybe it's too easy to do but I have no idea of how to do this, because reading and writing a file in Java has been a real problem for me since I started programming in Java (I'm a beginner). I have some ideas of using the BufferedReader and the StringTokenizer classes for the reading and creating the object problems, but I can't figure it out how to do it, and I have no idea of how must I do the overwritting problem. I'd really appreciate your help!
问题是这可能太容易了,但我不知道如何做到这一点,因为自从我开始用 Java 编程(我是初学者)以来,用 Java 读取和写入文件对我来说一直是一个真正的问题。我有一些使用 BufferedReader 和 StringTokenizer 类来读取和创建对象问题的想法,但我不知道如何去做,我也不知道我必须如何做覆盖问题。我真的很感激你的帮助!
Oh! By the way, I really need to use only the arrays, so using an ArrayList or any other structure it's not even a choice :(
哦!顺便说一句,我真的只需要使用数组,所以使用 ArrayList 或任何其他结构它甚至不是一个选择:(
采纳答案by Shar1er80
This is a good job for a Scanner
to read in the data. As far as not being able to use collections like ArrayList
you'll have to dynamically reallocate an array yourself.
这是Scanner
读取数据的好工作。至于不能像ArrayList
您必须自己动态重新分配数组那样使用集合。
Try the following:
请尝试以下操作:
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("Stock.txt"));
input.useDelimiter("-|\n");
Product[] products = new Product[0];
while(input.hasNext()) {
int id = input.nextInt();
String department = input.next();
String name = input.next();
double price = Double.valueOf(input.next().substring(1));
int stock = input.nextInt();
Product newProduct = new Product(name, price, department, id, stock);
products = addProduct(products, newProduct);
}
for (Product product : products) {
System.out.println(product);
}
}
private static Product[] addProduct(Product[] products, Product productToAdd) {
Product[] newProducts = new Product[products.length + 1];
System.arraycopy(products, 0, newProducts, 0, products.length);
newProducts[newProducts.length - 1] = productToAdd;
return newProducts;
}
public static class Product {
protected String name;
protected double price;
protected String department;
protected int id;
protected int stock;
private static NumberFormat formatter = new DecimalFormat("#0.00");
public Product(String n, double p, String d, int i, int s) {
name = n;
price = p;
department = d;
id = i;
stock = s;
}
@Override
public String toString() {
return String.format("ID: %d\r\nDepartment: %s\r\nName: %s\r\nPrice: %s\r\nStock: %d\r\n",
id, department, name, formatter.format(price), stock);
}
}
Results:
结果:
ID: 0
Department: Bakery
Name: Chocolate Cake
Price: 12.50
Stock: 250
ID: 1
Department: Meat
Name: Premium Steak
Price: 2.60
Stock: 120
ID: 2
Department: Seafood
Name: Tuna
Price: 1.20
Stock: 14
回答by gkc123
For simplicity, I have defined all the items as String.
为简单起见,我将所有项目定义为字符串。
Product DAO:
产品DAO:
public class Product {
private String name;
private String price;
private String department;
private String id;
private String stock;
//generate `enter code here`
//getters & setters
//toString
Put your product list in "testData/product.txt". This is assuming that your list of products comes in same format, i.e. id-department-name-price-stock \n.
将您的产品列表放在“testData/product.txt”中。这是假设您的产品列表采用相同格式,即 id-department-name-price-stock \n。
Use the jUnit test below to test your code. You can certainly modify how you read the product.txt file (may be other powerful string readers).
使用下面的 jUnit 测试来测试您的代码。您当然可以修改阅读 product.txt 文件的方式(可能是其他强大的字符串阅读器)。
@Test
public void test() {
try {
List<String> productLines = Files.readAllLines(java.nio.file.Paths.get("./testData/product.txt"), StandardCharsets.UTF_8);
for (String line: productLines)
Product product = new Product();
String[] tokens = line.split("-");
product.setId(tokens[0]);
product.setDepartment(tokens[1]);
product.setName(tokens[2]);
product.setPrice(tokens[3]);
product.setStock(tokens[4]);
System.out.println(product.toString())
}
} catch (IOException e) {
e.printStackTrace();
}
}
回答by granadaCoder
For future readers.
对于未来的读者。
I had double quotes surrounding my csv (comma separated values) file. And had some doubles and ints.
我的 csv(逗号分隔值)文件周围有双引号。并有一些双打和整数。
I also has going nuts trying to find a "bad line" and the value that was barfing.... in the csv file. Thus my exception with a decent message.
我也疯狂地试图在 csv 文件中找到一条“坏线”和令人讨厌的值......。因此,我的例外是一个体面的消息。
My "delimiter" is a comma and carriage return. And I deal with the double quotes "at the column level".
我的“分隔符”是逗号和回车符。我处理“在列级别”的双引号。
Here is what I came up with.
这是我想出的。
/* I know, a java example with the imports listed out ! shocking !! */
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
private void loadFromFile() {
Collection<MyCustomObject> items = new ArrayList<MyCustomObject>();
int lineNumber = 0;
String nextValue = "";
try {
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("MyFile.txt").getFile());
Scanner input = new Scanner(file)
.useDelimiter(",|\R")
.useLocale(Locale.ENGLISH);
;
/* skip the header */
input.nextLine();
while (input.hasNext()) {
lineNumber++;
nextValue = input.next().replace("\"", "");
String zipCodeValue =nextValue;
nextValue = input.next().replace("\"", "");
String city = nextValue;
nextValue = input.next().replace("\"", "");
String usaState = nextValue;
nextValue = input.next().replace("\"", "");
double latitude = Double.valueOf(nextValue);
nextValue = input.next().replace("\"", "");
double longitude = Double.valueOf(nextValue);
nextValue = input.next().replace("\"", "");
int population = Integer.valueOf(nextValue);
items.add(new MyCustomObject(zipCodeValue, city, usaState, latitude, longitude, population));
}
} catch (Exception ex) {
throw new RuntimeException(String.format("Line number '%s, nextValue '%s''", lineNumber, nextValue), ex);
}
}
Sample text (csv) file:
示例文本 (csv) 文件:
"ZIPCODE","CITY","STATE","LATITUDE","LONGITUDE","POPULATION"
"06778","NORTHFIELD","CT",41.707,-73.105,555
"06779","OAKVILLE","CT",41.595,-73.081,777
"06782","PLYMOUTH","CT",41.657,-73.041,888