Java 读取文本文件并创建二维数组
我有一个包含学生姓名和成绩的文本文件。我试图读取成绩,并将它们放入一个单独方法中的2d数组中,然后我想在main方法中调用它来打印数组。但是,如果我用它自己的方法调试代码,我会打印出所有内容,但是如果我在main方法中调用它,那么只打印出数组的最后一行。你们能告诉我我错过了什么吗 非常感谢你的帮助。 这是我的文本文件:Java 读取文本文件并创建二维数组,java,arrays,Java,Arrays,我有一个包含学生姓名和成绩的文本文件。我试图读取成绩,并将它们放入一个单独方法中的2d数组中,然后我想在main方法中调用它来打印数组。但是,如果我用它自己的方法调试代码,我会打印出所有内容,但是如果我在main方法中调用它,那么只打印出数组的最后一行。你们能告诉我我错过了什么吗 非常感谢你的帮助。 这是我的文本文件: John 25 5 4.5 5 4 5 10 10 6 9.5 5.5 Jim 25 5 4 5 4.5 5 10 4 10 9.5 7.5 Kathy 15 1 3 2
John 25 5 4.5 5 4 5 10 10 6 9.5 5.5
Jim 25 5 4 5 4.5 5 10 4 10 9.5 7.5
Kathy 15 1 3 2 1 1.5 8 2 4 3 4
Steve 21 5 3 2 1 4 5 6 7 8 8
Stacy 15 5 1 1 1 5 3 8 9 5 7
Faith 16 3 4 2 4 4 7 5 2 3 8
这是我的方法
public static double[][] processGrades(double[][] grade) throws IOException
{
PrintWriter writer = new PrintWriter(new FileOutputStream("Output.txt"));
Scanner readNum = null;
Scanner scan = null;
int count = 0;
int count2 = 0;
int width = 0;
String[] col = null;
String[][] tempGrade = null;
String line = null;
String line2 = null;
String[] newline = null;
int maxInLine = 0;
try
{
//Create Grades Array
scan = new Scanner(new FileInputStream("input.txt"));
scan.nextLine();
while(scan.hasNext())
{
line2 = scan.nextLine();
col = line2.split(" ");
width = col.length;
count++;
System.out.println(col.length);
}
tempGrade = new String[count][width];
grade = new double[count][width];
readNum = new Scanner(new FileInputStream("input.txt"));
readNum.nextLine();
//fill Grades array
for (int i = 0; i < grade.length && readNum.hasNextLine(); i++)
{
for (int j = 0; j < grade.length && readNum.hasNextLine(); j++)
{
tempGrade[i][j] = readNum.nextLine();
String tempNum = tempGrade[i][j].replaceAll("[^0-9.0 +$]","");
// get the lines
String[] lines = tempNum.split("\\r?\\n");
// get the max amt of nums in a single line
for (String x : lines)
{
String[] temp = x.split("\\s+");
// split on whitespace
if (temp.length > maxInLine)
{
maxInLine = temp.length;
}
}
String[][] array = new String[lines.length][maxInLine]; // declare and instantiate the array of arrays
for (int o = 0; o < lines.length; o++)
{
// split on whitespace
String[] temp = lines[o].split("\\s+");
for (int f = 1; f < maxInLine; f++)
{
array[o][f] = (temp[f]);
grade[o][f] = Double.parseDouble(array[o][f]);
}
}
}
}
readNum.close();
scan.close();
writer.close();
}
catch(FileNotFoundException e)
{
System.out.println("File Not Found");
}
return grade;
}
public static void main(String[] args) throws IOException, ParseException
{
PrintWriter writer = new PrintWriter(new FileOutputStream("Output.txt"));
String[] names = null;
double[][] grades = null;
double[][] grade = null;
double[][] min =null;
double[][] max =null;
double average =0;
grades = processGrades(grade);
for(int i=0; i < grades.length; i++)
{
for(int j=0; j < grades[i].length; j++)
{
System.out.println(grades[i][j]);
}
}
writer.close();
请原谅我,如果格式的文章是难以阅读或不正确。这是我第一次发布问题,不确定需要做什么。感谢 < P>我建议你考虑以下方法。它与您当前的代码有很大偏差,但在我看来,它要干净得多: 1) 创建一个类来构造一个学生
公共班级学生{
私有字符串名称;
private List grades;//可以是int的列表,具体取决于您需要什么
公立学生(字符串名称){
this.name=名称;
等级=新的ArrayList();
}
公共交通等级(双等级){
等级。添加(等级);
}
@凌驾
私有字符串toString(){
//重写调用Student.toString()进行打印时自动打印的内容
}
}
这里我们创建了一个学生抽象概念
2) 不同的文件读取方法:
公共静态列表加载(字符串文件)引发IOException{
List students=new ArrayList();
列表行=Files.readAllLines(path.get(file));
用于(字符串行:行){
如果(!line.isEmpty()){
ArrayList PartsOffline=拆分空间(行);
学生s=新学生(partsOfLine.get(0));
/*这里,如果等级数始终为n,只需使用
s、 setGrade(PartsOffline.get(1));
.
.
s、 setGrade(partsOfLine.get(n));
如果不是,则使用某种循环来设置所有等级*/
学生。添加(s)
}
}
return students;//此arrayList可以传递给打印方法
}
公共静态ArrayList splitOnSpace(字符串行){
String[]splits=line.split(“”);
返回新的ArrayList(Arrays.asList(splits));
}
3) 主要的样本打印方法
公共作废打印(列出学生){
(学生:学生){
System.out.println(s.toString());
}
}
我必须对双数组的大小进行硬编码,它可以工作。这是我更新的解决方案
public static void main(String[] arg) throws IOException {
double[][] grades = null;
double[][] gradelist = Grade(grades);
for(int i=0; i < gradelist.length; i++) {
for(int j=0; j < gradelist[i].length; j++) {
System.out.println(gradelist[i][j]);
}
}
}
public static double[][]Grade(double[][]grade) {
Scanner in = null;
try {
in = new Scanner(new FileInputStream("input.txt"));
in.nextLine();
int rows = 6;
int columns = 12;
grade = new double[rows][columns];
while(in.hasNextLine()) {
for (int i=0; i< grade.length; i++) {
String[] line = in.nextLine().trim().split(" ");
for (int j = 1; j < line.length; j++) {
grade[i][j] = Double.parseDouble((line[j]));
}
}
}
}
catch(Exception e) {
}
return grade;
}
publicstaticvoidmain(字符串[]arg)引发IOException{
双[][]等级=空;
双[][]等级列表=等级(等级);
对于(int i=0;i
很抱歉,但是。。。一团糟:-)使用reight抽象。在事情上使用好的名字。您的文件表示一个学生列表,其中有分数。所以使用一个列表,其中Student是一个类,其名称字段类型为String,成绩字段类型为double[]。将代码拆分为几个小方法,做一些简单的事情,比如将一行解析为一个学生,由另一个方法在循环中调用,将所有行解析为一个列表。仅在需要时声明变量,而不是在方法开头声明所有变量。是否需要使用标准数组?如果你考虑使用某种类型的集合,你可能会有一个更好的时间。@ JB NIZET——我知道它看起来很长,但是当我读文件时,似乎整个行被读取为1。我试图用两个等级来分隔字符串名称,但它不起作用。我唯一能让它工作并且知道如何工作的方法就是不断地分割线。如果你知道更好的方法,我将非常感谢你的帮助。Thanks@hb22-我还没学会收集。你必须分线。但是你不必把所有的代码都放在一个巨大的方法中。正如我在前面的评论中所说:您应该有一个单独的方法,它只解析(或者拆分,如果您愿意的话)一行并创建一个学生。另一个方法是通过对每行调用第一个方法,在各行中循环并创建一个学生列表(或一个数组或多个学生)。@ht22-我将尝试一下,并让您知道。非常感谢您的帮助。@ht22-我尝试了您的方法,但在这一行列表lines=Files.readAllLines(path.get(file))中不断出现错误;我必须更改为ArrayList,但它不会返回任何内容。我能想出一种不同的方法使它工作。非常感谢您的尝试。@Thi-hmm,我无法重现此错误。不管怎样,很高兴你找到了一个解决办法。@ht22-是的,我看到这里有很多帖子使用列表,但我不能。我正在使用eclipse,不确定这是什么原因。@该列表在集合层次结构中高于ArrayList,因此请确保导入的是List而不是ArrayList。这样,您可以使用列表声明或ArrayList。不过要小心。即使您声明了一个列表,您也必须用类似ArrayList的东西来实例化它。请帮助其他人在将来找到它。
public class Student {
private String name;
private List<Double> grades; // can be a list of int depending on what you need
public Student(String name) {
this.name = name;
grades = new ArrayList<Double>();
}
public void setGrade(Double grade) {
grades.add(grade);
}
@Override
private String toString() {
//Override what is automatically printed when you call Student.toString() to print
}
}
public static List<Student> load(String file) throws IOException {
List<Student> students = new ArrayList<Student>();
List<String> lines = Files.readAllLines(Paths.get(file));
for (String line : lines) {
if (!line.isEmpty()) {
ArrayList<String> partsOfLine = splitOnSpace(line);
Student s = new Student(partsOfLine.get(0));
/* Here, if the number of grades is consistently n, simply use
s.setGrade(partsOfLine.get(1));
.
.
s.setGrade(partsOfLine.get(n));
if not, use some sort of looping to set all grades */
students.add(s)
}
}
return students; // This arrayList can be passed to your print method
}
public static ArrayList<String> splitOnSpace(String line){
String[] splits = line.split(" ");
return new ArrayList<>(Arrays.asList(splits));
}
public void print(List<Students> students){
for (Student s: students) {
System.out.println(s.toString());
}
}
public static void main(String[] arg) throws IOException {
double[][] grades = null;
double[][] gradelist = Grade(grades);
for(int i=0; i < gradelist.length; i++) {
for(int j=0; j < gradelist[i].length; j++) {
System.out.println(gradelist[i][j]);
}
}
}
public static double[][]Grade(double[][]grade) {
Scanner in = null;
try {
in = new Scanner(new FileInputStream("input.txt"));
in.nextLine();
int rows = 6;
int columns = 12;
grade = new double[rows][columns];
while(in.hasNextLine()) {
for (int i=0; i< grade.length; i++) {
String[] line = in.nextLine().trim().split(" ");
for (int j = 1; j < line.length; j++) {
grade[i][j] = Double.parseDouble((line[j]));
}
}
}
}
catch(Exception e) {
}
return grade;
}