从文件中读取 class 的对象数组
Reading array of objects of a class from a file
我有一个包含三个字段的 class,两个 int
和一个 double
。我已经列出了我的 class 对象,并想使用 Scanner
、BufferedReader
和 FileReader
从文本文件中逐行读取数组的对象.
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);
}
}
您不能将字符串数组解析为双精度数:Double.parseDouble(line)
.
您也不能将 double 分配给对象引用(即:Sleg
此处):list2[sl] = Double.parseDouble(line)
.
读取下一行的操作应该放在外层while循环中:String[] line = in7.nextLine().trim().split(" ");
.
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++;
}
我有一个包含三个字段的 class,两个 int
和一个 double
。我已经列出了我的 class 对象,并想使用 Scanner
、BufferedReader
和 FileReader
从文本文件中逐行读取数组的对象.
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);
}
}
您不能将字符串数组解析为双精度数:
Double.parseDouble(line)
.您也不能将 double 分配给对象引用(即:
Sleg
此处):list2[sl] = Double.parseDouble(line)
.读取下一行的操作应该放在外层while循环中:
String[] line = in7.nextLine().trim().split(" ");
.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++;
}