简体   繁体   English

如何从文件中读取并将其存储在对象的 ArrayList 中?

[英]How to read from files and store it in ArrayList of objects?

This is my save method这是我的保存方法

public static void save() {
        try {
            PrintWriter myWriter = new PrintWriter("database.txt");
            for(int i=0; i<people.size(); i++) {
                myWriter.println(people.get(i).toString());
            }
            myWriter.close();
            System.out.println("Successfully wrote to the file.");
            menu();
        } catch (IOException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
    }

This is what it looks like in the file这是文件中的样子

    Donald     Trump  23323.00

This is the fields and the name of the arraylist这是数组列表的字段和名称

ArrayList<Person> people = new ArrayList<Person>();
public Person(String name, String password, double money) {
        this.name = name;
        this.password = password;
        this.money = money;
    }
constructors below.....

How do i read that file and store it in the arraylist of objects?我如何读取该文件并将其存储在对象的数组列表中? Need help :D需要帮助:D

Not that there is anything wrong with the way you have written to your data text file, it's just that I think it is better to follow a more conventional CSV style file format which is specific for data storage of this type.并不是说您写入数据文本文件的方式有什么问题,只是我认为最好遵循更传统的CSV样式文件格式,该格式专门用于此类数据存储。

For example, each line within a CSV file is considered a record row and typically a comma (,) is used to separate columns of field data within that row instead of a whitespace or tab (like in your file) and there is obviously good reason for that.例如,CSV 文件中的每一行都被视为一个记录行,通常使用逗号 (,) 来分隔该行中的字段数据列,而不是空格或制表符(如您的文件中),这显然是有充分理由的为了那个原因。 Eventually that data within the file will need to be retrieved, what if a column field contains a whitespace in it?最终需要检索文件中的数据,如果列字段中包含空格怎么办? Some last names for example contain two words (Simone de Beauvoir, Herbert M. Turner III, Ashley M. St. John, etc).例如,一些姓氏包含两个词(Simone de Beauvoir、Herbert M. Turner III、Ashley M. St. John 等)。 Some consideration must be given for this and yes, there is definitely a work-around for this but all in all, it's just easier to utilize a more specific delimiter other that whitespace.必须对此进行一些考虑,是的,肯定有一种解决方法,但总而言之,使用除空格之外的更具体的分隔符更容易。 You may want to consider changing your whitespace delimiter for perhaps a comma or semicolon delimiter.您可能需要考虑将空格分隔符更改为逗号或分号分隔符。 You could even provide this as an option within your Person class toString() method:您甚至可以在Person类的toString()方法中将此作为选项提供:

/* Example Person Class...    */
import java.io.Serializable;

public class Person implements Serializable {

    // Default serialVersion id
    private static final long serialVersionUID = 1212L;

    private String name;
    private String password;
    private double money;

    public Person() { }

    public Person(String name, String password, double money) {
        this.name = name;
        this.password = password;
        this.money = money;
    }

    public String toString(String delimiterToUse) {
        return new StringBuffer("").append(this.name).append(delimiterToUse)
                                   .append(this.password).append(delimiterToUse)
                                   .append(String.format("%.2f", this.money)).toString();
    }

    @Override
    public String toString() {
        return new StringBuffer("").append(this.name).append(" ")
                                   .append(this.password).append(" ")
                                   .append(String.format("%.2f", this.money)).toString();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

And in your save() method you might have your existing line to utilize the class default delimiter of whitespace ( " " ):在你的save()方法中,你可能有你现有的行来利用空格的类默认分隔符 ( " " ):

myWriter.println(people.get(i).toString());

or utilize a different delimiter like a comma/space combination ( ", " ):或使用不同的分隔符,如逗号/空格组合", " ):

    myWriter.println(people.get(i).toString(", "));

The data records in file would then look something like:文件中的数据记录将类似于:

Donald Trump, myPassword, 23323.0

This data line directly above would now be easier to parse using something like the String#split() method, for example:现在使用String#split() 之类的方法可以更轻松地解析正上方的此数据行,例如:

public static List<Person> readInPeople(String databaseFile) {
    /* Declare a List Interface to hold all the read in records 
       of people from the database.txt file.        */
    List<Person> people = new ArrayList<>();

    // 'Try With Resouces' is used to so as to auto-close the reader.
    try (BufferedReader reader = new BufferedReader(new FileReader("database.txt"))) {
        String dataLine;
        while ((dataLine = reader.readLine()) != null) {
            dataLine = dataLine.trim();
            // Skip past blank lines.
            if (dataLine.equals("")) {
                continue;
            }

            /* Split the read in dataline delimited field values into a 
               String Array. A Regular Expression is used within the split()
               method that takes care of any comma/space delimiter combination
               situation such as: "," or ", " or " ," or " , "   */
            String[] dataLineParts = dataLine.split("\\s{0,},\\s{0,}");

            // Ensure defaults for people.
            String name = "", password = "";
            double money = 0.0d;

            /* Place each split data line part into the appropriate variable 
               IF it exists otherwise the initialized default (above) is used. */
            if (dataLineParts.length >= 1) {
                name = dataLineParts[0];
                if (dataLineParts.length >= 2) {
                    password = dataLineParts[1];
                    if (dataLineParts.length >= 3) {
                        /* Make sure the data read in is indeed a string
                           representation of a signed or unsigned Integer 
                           or double/float type numerical value. The Regular
                           Expression within the String#matches() method 
                           does this.                                    */
                        if (dataLineParts[2].matches("-?\\d+(\\.\\d+)?")) {
                            money = Double.parseDouble(dataLineParts[2]);
                        }
                    }
                }
            }

            // Add the person from file into the people List.
            people.add(new Person(name, password, money));
        }
    }
    // Catch Exceptions...
    catch (FileNotFoundException ex) {
        System.err.println(ex.getMessage());
    }
    catch (IOException ex) {
        System.err.println(ex.getMessage());
    }
    /* Return the list of people read in from the 
       database text file.   */
    return people;
}

To use this method you might do it something like this:要使用此方法,您可以这样做:

// Call the readInPeople() method to fill the people List.
List<Person> people = readInPeople("database.txt");

/* Display the people List in Console Window 
   using a for/each loop.     */
// Create a header for the data display.
// Also taking advantage of the String#format() and String#join() methods.
// String#join() is used to create the "=" Header underline.
String header = String.format("%-20s %-15s %s\n", "Name", "Password", "Money");
header += String.join("", Collections.nCopies(header.length(), "="));
System.out.println(header);

// Display the list. Also taking advantage of the printf() method.
for (Person peeps : people) {
    System.out.printf("%-20s %-15s %s\n", peeps.getName(), peeps.getPassword(), 
                      String.format("%.2f", peeps.getMoney()));
}

The Console display could look something like this:控制台显示可能如下所示:

Name                 Password        Money
===========================================
Donald Trump         myPassword      23323.00
Tracey Johnson       baseball        2233.00
Simone de Beauvoir   IloveFrance     32000.00

Read the file line by line and use same delimiter you have used in toString of Person class.逐行读取文件并使用您在Person类的toString中使用的相同分隔符。

Like: let se you have used " " as delimiter.就像:假设您使用了" "作为分隔符。

then read line by line and split the data using that delimiter and convert the data respectively然后逐行读取并使用该分隔符拆分数据并分别转换数据

String line = reader.readLine();
String[] array = line.split(" ")// use same delimiter used to write
if(array.lenght() ==3){ // to check if data has all three parameter 
    people.add(new Person(array[0], array[1], Double.parseDouble(array[2]))); 
    // you have to handle case if Double.parseDouble(array[2]) throws exception
}

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

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