我想在Java中读取自定义文本文件中的值。
下面是我的文本文件:
Classroom1
Student1 Name, Student1 Surname , Student1 Age
Student2 Name, Student2 Surname , Student2 Age
Student3 Name, Student3 Surname , Student3 Age
Student4 Name, Student4 Surname , Student4 Age
...
Classroom2
Student1 Name, Student1 Surname , Student1 Age
Student2 Name, Student2 Surname , Student2 Age
Student3 Name, Student3 Surname , Student3 Age
Student4 Name, Student4 Surname , Student4 Age
...
Classroom3
...
我试图实现一些编码的东西,但我无法处理这个过程。
我想把所有的学生都加到每个教室。我想使用Map<String,List<Student>>
来处理这个问题,但我无法实现读取值的过程。
我该怎么做呢?
代码片段如下所示:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in); // detect inputs from the terminal input, System.in
List<Student> students;
while(in.hasNextLine()) { // while the scanner has a next line
in.nextLine();
String[] s = in.nextLine().split(",");
students.add(new Student(s[0], s[1], s[2]));
}
}
public class Student {
public String name;
public String surname;
public int age;
public Student(String name, String surname, int age) {
// ...
}
}
}
您在问题中写道:
我想把所有的学生都加到每个教室。我想使用Map<String,List>
我假设Map
键是教室的名称,例如Classroom1,它单独出现在一行,在您的问题中的示例文件(名为students.txt)中。Map
值即为该班学生的List
值。
(代码后面的注释)
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class Student {
private String name;
private String surname;
private int age;
public Student(String name, String surname, int age) {
this.name = name;
this.surname = surname;
this.age = age;
}
public static void main(String[] args) {
Path source = Paths.get("students.txt");
try (Scanner s = new Scanner(source)) {
Map<String, List<Student>> classrooms = new HashMap<>();
String classroom = "";
while (s.hasNextLine()) {
String line = s.nextLine();
if (line.startsWith("Classroom")) {
classroom = line;
classrooms.put(classroom, new ArrayList<Student>());
}
String[] fields = line.split(",");
if (fields.length == 3) {
try {
int age = Integer.parseInt(fields[2].trim());
Student stud = new Student(fields[0].trim(), fields[1].trim(), age);
List<Student> students = classrooms.get(classroom);
students.add(stud);
}
catch (NumberFormatException xNumberFormat) {
// Ignore
}
}
}
}
catch (IOException xIo) {
xIo.printStackTrace();
}
}
}
- 你不需要一个单独的类,只有一个
main
方法,为了运行你的程序。Student
类也可以包含main
方法。 - 问题中的代码试图从用户获取值,而不是读取students.txt文件。
- 根据您的问题中的示例数据,在students.txt文件中的一些行上的逗号周围有空格。因此调用方法trim。
- 上面的代码使用了try-with-resources。
- 您需要将包含学生详细信息的行的最后一个字段从
String
转换为int
。因此调用方法parseInt
。该方法可能抛出NumberFormatException
,因此调用在try-catch中。如果String
不能转换为int
,那么我就忽略那一行。你也许想干点别的。我无法从你的问题中确定你如何处理student.txt文件中的无效行,即不包含预期数据的行。 - 接口
java.util.Map
的get
方法可能返回null。上面的代码没有处理这种情况,因为它不应该发生。你可能需要修改上面的代码,这样它就可以处理方法get
返回null的情况。
我不确定这个答案是否正是你想要寻找的,但我已经尽力猜测你可能想要做什么:)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
public class Main {
public static final String FILE_PATH = "src/students.txt";
public static final String STUDENT_FIELDS_SEPARATOR = ",";
public static final String CLASSROOM_SEPARATOR = "...";
public static void main(String[] args) {
Map<String, List<Student>> classroomMap = parseStudentsFile();
System.out.println(classroomMap);
}
private static Map<String, List<Student>> parseStudentsFile() {
try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH))) {
AtomicReference<String> currClassroom = new AtomicReference<>("");
return reader.lines().map(line -> {
String[] splitLine = line.split(STUDENT_FIELDS_SEPARATOR);
if (splitLine.length == 1 && !splitLine[0].equals(CLASSROOM_SEPARATOR)) {
currClassroom.set(splitLine[0]);
} else if (splitLine.length == 3) {
try {
return Map.entry(currClassroom, new Student(splitLine[0].strip(), splitLine[1].strip(), Integer.parseInt(splitLine[2].strip())));
} catch (NumberFormatException e) {
System.out.println("NumberFormatException - line ignored, cannot parse: " + line);
return null;
}
} else return null;
return null;
})
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(
o -> o.getKey().toString(),
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
public class Student {
private final String name;
private final String surname;
private final int age;
public Student(String name, String surname, int age) {
this.name = name;
this.surname = surname;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", surname='" + surname + ''' +
", age=" + age +
'}';
}
}
students.txt
Classroom1
Student1 Name, Student1 Surname , 1
Student2 Name, Student2 Surname , 2
Student3 Name, Student3 Surname , 3
Student4 Name, Student4 Surname , 4
...
Classroom2
Student1 Name, Student1 Surname , 1
Student2 Name, Student2 Surname , 2
Student3 Name, Student3 Surname , 3
Student4 Name, Student4 Surname , 4
...
输出{Classroom2=[Student{name='Student1 Name', surname='Student1 Surname', age=1}, Student{name='Student2 Name', surname='Student2 Surname', age=2}, Student{name='Student3 Name', surname='Student3 Surname', age=3}, Student{name='Student4 Name', surname='Student4 Surname', age=4}], Classroom1=[Student{name='Student1 Name', surname='Student1 Surname', age=1}, Student{name='Student2 Name', surname='Student2 Surname', age=2}, Student{name='Student3 Name', surname='Student3 Surname', age=3}, Student{name='Student4 Name', surname='Student4 Surname', age=4}]}
通常需要从特定类型的文件(如.xml或类似的文件)中读取此类数据。在您的情况下,您必须找到一种方法来消除所有空格和附加字符,并从每行[Name,姓氏,年龄]中提取。解决方案如下:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class ReadFile {
public static void main(String[] args) throws FileNotFoundException {
File file = new File(filePath);
Scanner in = new Scanner(file);
ArrayList<Student> students = new ArrayList<Student>();
while (in.hasNextLine()) { // while the scanner has a next line
String[] s = in.nextLine().split(",");
if (!s[0].equals("...") && !s[0].contains("Classroom")) {
String[] age = s[2].split(" ");
String[] name = s[0].split(" ");
String[] surname = s[1].split(" ");
students.add(new Student(name[1], surname[2],Integer.parseInt(age[2])));
}
}
for (Student student : students) {
System.out.println(student.toString());
}
}
public static class Student {
public String name;
public String surname;
public int age;
public Student(String name, String surname, int age) {
this.name = name;
this.surname = surname;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", surname='" + surname + ''' +
", age=" + age +
'}';
}
}
}