构建一个方法,将包含多个变量的文本文件读入数组,而不使用Java中的ArrayList



我已经指示建立一个学生类,包括不同的变量,包括字符串名称,int标记物理等。然后,我的目标是构建一个方法来读取包含这些数据的文本文件,而不使用ArrayList。之后,我需要对数组进行排序。但是我在将txt文件的数据放入数组时遇到了问题。

代码如下:

public class Main2{
public static void main(String[] args) throws FileNotFoundException {
String filename = "students.txt";
Student[] record = readData(filename);
record = new Student [record.length];
for(int i = 0; i < record.length; i++){
System.out.println(record[i]);
}
}
//Method for read data from the .txt file into an array
private static Student[] readData(String filename){
int arraysize = 0;
try{
Scanner s1 = new Scanner(new File(filename));
//Count elements in the file
while(s1.hasNext()){
arraysize++;
s1.next();
}
//Create an array and copy the elements into it
Student[] studentRecord = new Student[arraysize];
Scanner s2 = new Scanner(new File(filename));
for(int i = 0; i < arraysize; i++){
studentRecord[i].name = s2.next();
studentRecord[i].physic = s2.nextInt();
studentRecord[i].chemistry = s2.nextInt();
studentRecord[i].math = s2.nextInt();
studentRecord[i].average = (double)(studentRecord[i].physic + studentRecord[i].chemistry + studentRecord[i].math)/3;
// double roundedAvg = Math.round(average * 100.0) / 100.0;
// studentRecord[i].average = Math.round((physic + chemistry + math)/3 * 100.0)/100.0;
}
return studentRecord;
}
catch(FileNotFoundException e){
}
return null;
}

}

文本文件包括如下记录:

Jack  77      84       93
Tod   84      86       80
Name marksP marksC   marksM

代码可以编译,但当我运行代码。它显示了

Exception in thread "main" java.lang.NullPointerException: Cannot assign field "name" because "<local3>[<local5>]" is null
at Main2.readData(Main2.java:40)
at Main2.main(Main2.java:10)

是因为学生班吗?但是我已经将Student Class属性初始化为:

public Student(String name, int m1, int m2, int m3, double avg){
this.name = name;
int.mark1 = m1;
...
}

我做错了什么?我如何修复代码?当我在Student类中初始化时,该名称不应该为空。

在您的for循环中,您从文件中读取数据,您的studentRecord尚未包含实际的Student对象。到目前为止,它只是一个占位符,可以容纳指定数量的Student对象。因此,您需要实际创建Student对象来存储在指定的数组中。

为此,读取数据,将其临时存储在变量中,然后通过已经拥有的构造函数创建每个Student对象。

所以它应该看起来像这样:

for(int i = 0; i < arraysize; i++){
String name = s2.next();
int physic = s2.nextInt();
int chemistry = s2.nextInt();
int math = s2.nextInt();
double average = (double)(physic + chemistry + math) / 3;
Student myStudent = new Student (name, physic, chemistry, math, average);
studentRecord[i] = myStudent;
}

另外,你现在计算数组大小不正确。您需要计算行数,而不是每个标记。更像这样:

while(s1.hasNextLine()){
arraysize++;
s1.nextLine();
}

我发现的第一个问题是您计算文件中学生人数的方式。如果你知道你的students.txt文件的行数正好等于学生人数(没有标签或任何可以延伸到多行的东西),那么你可以这样计数:

while(scan.hasNext()) {
lines++;
scan.nextLine();
}

第二个问题是关于数组的创建。当你像这样初始化一个数组时:

final Student[] students = new Students[length];

它将创建数组,它将充满null元素:[null, null, null,... ]。但是这些null元素不是你的Student对象。所以你可以用空对象填充数组然后在后面的代码中改变它们的属性:

final Student[] students = new Students[length];
Arrays.fill(students, new Student("default", 100, 100, 100);

提示:您可以像这样将平均值的计算移到Student类的构造函数中,并根据用例链接尝试使用更小或更大的日期类型。:

public Student(String name, byte physics, byte chemistry, byte math) {
this.name = name;
this.physics = physics;
this.chemistry = chemistry;
this.math = math;
this.avg = (math + chemistry + physics) / 3.0;
}

现在我们不需要为Student对象设置或覆盖变量。当有重复的代码时,可能有更好的方法来编写它(不是所有时候)。

for (int i = 0; i < lines; i++) {
students[i] = new Student(fileScanner.next(), fileScanner.nextByte(), fileScanner.nextByte(), fileScanner.nextByte());
System.out.println(students[i]);
}

我认为你的问题是你没有完全理解当你执行

时发生了什么
Student[] studentRecord = new Student[arraysize];

这将创建一个名为studentRecord的数组,该数组具有特定的大小。它不会创建任何Student类型的对象放入这个数组。你的数组将只包含null。

要解决这个问题,你需要这样做:

for(int i = 0; i < arraysize; i++) {
studentRecord[i] = new Student();
studentRecord[i].name = s2.next();

最新更新