简体   繁体   English

从文本文件中读取数据并创建对象

[英]Read data from a text file and create an object

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 0-面包店-巧克力蛋糕-$12.5-250
  • 1-Meat-Premium Steak-$2.6-120 1-Meat-Premium Steak-$2.6-120
  • 2-Seafood-Tuna - $1.2-14 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.其中第一个数字是产品的“id”,其次是产品所属的部门,第三个是产品名称,接下来是价格,最后一个数字是该产品的库存数量. I have this class:我有这门课:

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, ie 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).问题是这可能太容易了,但我不知道如何做到这一点,因为自从我开始用 Java 编程(我是初学者)以来,用 Java 读取和写入文件对我来说一直是一个真正的问题。 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.我有一些使用 BufferedReader 和 StringTokenizer 类来读取和创建对象问题的想法,但我不知道如何去做,我也不知道我必须如何做覆盖问题。 I'd really appreciate your help!我真的很感激你的帮助!

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 或任何其他结构甚至都不是一个选择:(

This is a good job for a Scanner to read in the data.这是一个很好的Scanner读取数据的工作。 As far as not being able to use collections like ArrayList you'll have to dynamically reallocate an array yourself.至于不能使用像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

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".将您的产品列表放在“testData/product.txt”中。 This is assuming that your list of products comes in same format, ie id-department-name-price-stock \\n.这是假设您的产品列表采用相同格式,即 id-department-name-price-stock \\n。

Use the jUnit test below to test your code.使用下面的 jUnit 测试来测试您的代码。 You can certainly modify how you read the product.txt file (may be other powerful string readers).您当然可以修改阅读 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();
        }

    } 

For future readers.对于未来的读者。

I had double quotes surrounding my csv (comma separated values) file.我的 csv(逗号分隔值)文件周围有双引号。 And had some doubles and ints.并有一些双打和整数。

I also has going nuts trying to find a "bad line" and the value that was barfing.... in the csv file.我也疯狂地试图在 csv 文件中找到一条“坏线”和令人讨厌的值......。 Thus my exception with a decent message.因此,我的例外是一个体面的消息。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM