从文件中读取 class 的对象数组

Reading array of objects of a class from a file

我有一个包含三个字段的 class,两个 int 和一个 double。我已经列出了我的 class 对象,并想使用 ScannerBufferedReaderFileReader 从文本文件中逐行读取数组的对象.

MWE:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Model {
    public static final int Y = 7;
    public static final int K = 42;
    public static final int G = 3;

public static class Sleg {
        // private int id;
        private int i;
        private int j;
        private double l;

        public Sleg(int i, int j, double l) {
            // this.id = id;
            this.i = i;
            this.j = j;
            this.l = l;
        }

        @Override
        public String toString() {
            return Integer.toString(i) + " " + Integer.toString(j) + " " + Double.toString(l);
        }
    }


    public static void dataGen() {

        System.out.print("slegs = ");


          /*List<Sleg> slegs = Arrays.asList(); I want to write it like this and 
          read it from slFile.txt instead of the following line where the slegs are put one by one.*/
        List<Sleg> slegs = Arrays.asList(new Sleg(1,2,400),new Sleg(2,5,800),new Sleg(5,7,450),new Sleg(2,3,800),new Sleg(3,6,500),new Sleg(3,4,500),new Sleg(4,5,500),new Sleg(7,5,450),new Sleg(5,4,500),new Sleg(4,3,400),new Sleg(6,3,550),new Sleg(3,2,700),new Sleg(2,1,400), new Sleg(5,2,800));

        System.out.print(slegs);
        System.out.println("]");

        System.out.print("slegs = [");
        for (Sleg s : slegs) {
            System.out.print(s);
        }
        System.out.println("]");

        System.out.print("slegs = [");
        Sleg list2[] = new Sleg[slegs.size()];
        list2 = slegs.toArray(list2);

        File slFile = new File("slFile.txt");
        try {
            Scanner in7 = new Scanner(new BufferedReader(new FileReader("slFile.txt")));

            while(in7.hasNextLine()) {
                for (int sl = 0; sl < list2.length; sl++) {
                    String[] line = in7.nextLine().trim().split(" ");
                    list2[sl] = Double.parseDouble(line);                
                }
            }

        } catch (FileNotFoundException e) {
            System.out.println("Unable to read : " + slFile.toString());
        }

        for (Sleg i : list2) {
            System.out.print(i);
        }
        System.out.println("]");

        System.out.print("slegs = [");
        Object[] ss = slegs.toArray();
        for (int i = 0; i < ss.length; i++) {
            System.out.print(ss[i]);
        }
        System.out.println("]");


          int[][] u = new int [slegs.size()][G];
    }
}

slFile.tex中的数据:

1 2 400
2 5 800
5 7 450
2 3 800
3 6 550
3 4 500
4 5 500
7 5 450
5 4 500
4 3 400
6 3 550
3 2 700
2 1 400
5 2 800

但是,弹出错误“将行更改为字符串”。如果我有一个 3 维数组而不是包含 3 个字段的 class Sleg 的 slegs 对象,我知道如何读取该文件,但为此我不知道。 我会很感激你的想法!

您提供的代码存在一些问题。您正在尝试将 Boolean.parseBoolean(String)String[] 一起使用,您假设文本文件中的行数,list2 变量的类型为 Sleg[] 但您重新尝试将 double 分配给它的元素,以及其他各种东西。

假设您只对将文件读入 Slug 对象列表感兴趣,您可能想做这样的事情:

// Use a list since the length of the file is unkown
List<Sleg> slegs = new ArrayList<Sleg>();

File slFile = new File("slFile.txt");

// Use try-with-resources block so the reader is closed automatically,
// no need to use Scanner since we're only interested in reading lines...
try (BufferedReader reader = new BufferedReader(new FileReader("slFile.txt"))) {

    // Read the file line by line
    String line;
    while ((line = reader.readLine()) != null) {
        // Split the line, convert values, and add new sleg.
        String[] numbers = line.trim().split(" ");
        int i = Integer.parseInt(numbers[0]);
        int j = Integer.parseInt(numbers[1]);
        double l = Double.parseDouble(numbers[2]);
        slegs.add(new Sleg(i, j , l));
    }

} catch (FileNotFoundException e) {
    System.out.println(slFile.toString() + " does not exist.");
} catch (IOException e) {
    // Handle any possible IOExceptions as well...
    System.out.println("Unable to read : " + slFile.toString());
} 

好吧,我使用了 LinkedList,因为我不知道那里有多少 items/lines(我本可以数一数,但如果没有指示有多少行,即第一行指示项目的数量......我将使用链表)。现在,您的方法 dataGen 将 return 一个 LinkedList 存储 Sleg 对象。这是一个有效的 MVCE:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.LinkedList;
import java.util.Scanner;

public class Model {

    public static final int Y = 7;
    public static final int K = 42;
    public static final int G = 3;

    public Model() {

        dataGen();
    }

    public LinkedList<Sleg> dataGen() {
        LinkedList<Sleg> data = new LinkedList<>();
        File slFile = new File("slFile.txt");
        try {
            Scanner in7 = new Scanner(new BufferedReader(new FileReader("slFile.txt")));
            while (in7.hasNextLine()) {
                //get current line and split it via a space.
                String[] split = in7.nextLine().split(" ");
                int x = Integer.parseInt(split[0]);
                int y = Integer.parseInt(split[1]);
                double z = Double.parseDouble(split[2]);
                Sleg newItem = new Sleg(x, y, z);//new entry.
                data.add(newItem);//add as an entry to data.
            }
            in7.close();//should have this!!!
        } catch (FileNotFoundException e) {
            System.out.println("Unable to read : " + slFile.toString());
        }
        for (Sleg current : data) {
            System.out.println(current.toString());
        }
        return data;
    }

    public static void main(String[] args) {
        new Model();
    }

    class Sleg {

        int x = 0;
        int y = 0;
        double z = 0;

        Sleg(int x, int y, double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        @Override
        public String toString() {
            return "(" + x + ", " + y + ", " + z + ")";
        }
    }
}

问题在这里:

while(in7.hasNextLine()) {
    for (int sl = 0; sl < list2.length; sl++) {
        String[] line = in7.nextLine().trim().split(" ");
        list2[sl] = Double.parseDouble(line);                
    }
}
  1. 您不能将字符串数组解析为双精度数:Double.parseDouble(line).

  2. 您也不能将 double 分配给对象引用(即:Sleg 此处):list2[sl] = Double.parseDouble(line).

  3. 读取下一行的操作应该放在外层while循环中:String[] line = in7.nextLine().trim().split(" ");.

  4. for 循环是不必要的,因为每个循环只处理一个元素(不是 list2 中的所有元素)。

在上述基础上,可修改为:

int sl = 0;
while(in7.hasNextLine() && sl < list2.length) {
    String[] line = in7.nextLine().trim().split(" ");
    if (line.length < 3) {
        System.out.println("invalid line: " + line);
        continue;
    }
    list2[sl] = new Sleg(
        Integer.parseInt(line[0]),
        Integer.parseInt(line[1]),
        Double.parseInt(line[2])
    );
    sl++;
}