访问对象数组列表中的特定元素

Accessing specific elements in Arraylist of Objects

真的很困惑如何只访问特定学生的年龄,因为学生的所有信息都存储在一个文本文件中。我正在读取文本文件并将该信息存储到学生对象中,只是需要有关访问此文件的帮助。

public class Student {
    private String lName;
    private int idNumber;
    private int age;

    public Student() {
        lName = "";
        idNumber = 0;
        age = 0;
    }
    public Student(String l, int i, int a) {
        lName = l;
        idNumber = i;
        age = a;
    }

    public void setName(String last) {
        lName = last;
    }

    public String getName() {
        return lName;
    }

    public void setIdNum(int num) {
        idNumber = num;
    }

    public int getIdNum() {
        return idNumber;
    }

    public void setAge(int a) {
        age = a;
    }

    public int getAge() {
        return age;
    }
}

我的文本文件看起来像这样:此信息存储在并行数组列表中。我不太明白如何将其实现到对象中以将其传递到我的第二个承包商方法中。

  Josh          2134         19
  Smith         5256         21
  Rogers        9248         19
  Andrew        7742         20

这是我试过的方法;

public static void main(String[] args) {
    String file = "studentData.txt";
    Scanner reader = new Scanner(file);

    ArrayList<Student> users = readFile(file);
    Student s = new Student();
    users.add(s);


    Scanner input = new Scanner(System.in);
    //user enters idNumber to display age
    System.out.println("Enter ID Number"); //exception handling to be added
    int idNum = input.nextInt();

//this part is where I'm stuck 
    for(int i = 0; i < users.get(i) i++){
    if(idNum == users.get(i)){
     users.setAge(i);
}
}
     System.out.println(users.getAge());

}
//METHOD FOR READING FILE
 public static ArrayList<Student> readFile(String file)throws IOException{
    Scanner reader = new Scanner(new File(file));

    ArrayList<Student> list = new ArrayList<Student>();//creates ArrayList with student object

    reader.nextLine();//skips first line
    while(reader.hasNext()){//splits all text in the file into words
      String lName = reader.next();
      int idNum = reader.nextInt();
      int age = reader.nextInt();
      
    Student users = new Student(lName ,idNum, age); 
     list.add(users);
    }
    
   return list;

}//end method

我想解决这个问题的唯一方法是读取文件 3 次,将姓名、身份证号和年龄存储在单独的数组列表中。然后使用该单独的数组列表使用 ageList.get(i) 来存储年龄。我相信那将是超级不必要的??

您可以像这样将方法链接在一起。

      for(int i = 0; i < users.size(); i++){
         if(idNum == users.get(i).getIdNum()){
            final Student temp = users.get(i);
            System.out.println("Student with an ID of " + temp.getIdNum() + " has an age of " + temp.getAge());
         }
      }

在这里,我链接 users.get(i) 以在索引 i 处获取 Student,然后我调用 getIdNum(),它从 Student 获取 ID我刚拿的。

然后,我执行 == 比较 --> 用户输入的 ID 是否与我正在查看的这个特定 Student 的 ID 相同?

如果结果为真,我会再次调用 users.get(i),这会再次获取相同的 Student,然后将其存储到名为 [=22] 的临时 Student 变量中=]. temp 现在在通过 ID 检查的 ArrayList 上引用 Student

然后,我采用 temp,并使用它具有的 getIdNum()getAge() 方法(因为 tempStudent 的一个实例, Student 有这些方法),并使用它们创建一条消息,我将其打印到命令行上。

这是一个完整的、可运行的示例。

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

public class SOQ_20220514
{

   public static class Student {
      private String lName;
      private int idNumber;
      private int age;
   
      public Student() {
         lName = "";
         idNumber = 0;
         age = 0;
      }
      public Student(String l, int i, int a) {
         lName = l;
         idNumber = i;
         age = a;
      }
   
      public void setName(String last) {
         lName = last;
      }
   
      public String getName() {
         return lName;
      }
   
      public void setIdNum(int num) {
         idNumber = num;
      }
   
      public int getIdNum() {
         return idNumber;
      }
   
      public void setAge(int a) {
         age = a;
      }
   
      public int getAge() {
         return age;
      }
   }

   public static void main(String[] args) throws IOException {
      String file = "studentData.txt";
      Scanner reader = new Scanner(file);
   
      ArrayList<Student> users = readFile(file);
      Student s = new Student();
      users.add(s);
   
   
      Scanner input = new Scanner(System.in);
    //user enters idNumber to display age
      System.out.println("Enter ID Number"); //exception handling to be added
      int idNum = input.nextInt();
   
   //this part is where I'm stuck 
      for(int i = 0; i < users.size(); i++){
         if(idNum == users.get(i).getIdNum()){
            final Student temp = users.get(i);
            System.out.println("Student with an ID of " + temp.getIdNum() + " has an age of " + temp.getAge());
         }
      }
   
   }
//METHOD FOR READING FILE
   public static ArrayList<Student> readFile(String file)throws IOException{
      Scanner reader = new Scanner(new File(file));
   
      ArrayList<Student> list = new ArrayList<Student>();//creates ArrayList with student object
   
      reader.nextLine();//skips first line
      while(reader.hasNext()){//splits all text in the file into words
         String lName = reader.next();
         int idNum = reader.nextInt();
         int age = reader.nextInt();
      
         Student users = new Student(lName ,idNum, age); 
         list.add(users);
      }
    
      return list;
   
   }//end method

}

看起来是正确的。为了好玩,这里有一个替代方案。

提供输入数据。我将用 String 模拟一个文件作为文本输入。

String input =
        """
        Josh,2134,19
        Smith,5256,21
        Rogers,9248,19
        Andrew,7742,20     
        """;

定义一个Studentclass来保存数据。如果此 class 的主要目的是透明且不可变的数据通信,请使用 record。编译器隐式创建构造函数、getter、equals & hashCodetoString.

record Student( String name , int id , int age ) { }

请注意,我们可以在本地方法中声明一个 record。或者声明嵌套在另一个 class 中,或者单独声明。

接下来我们使用流在单个语句中完成大量工作。

首先,我们为输入文本中的每一行创建一个流。通过调用String#lines,我们得到一个Stream< String >,一系列String.

类型的元素

对于其中的每一行,我们调用 Stream#map 来创建另一个流。我们用逗号字符分割每一行,得到一个字符串数组,String[]。每个数组有三个元素,每行三个信息。

对于行部分的每个字符串数组,我们再次调用 Stream#map 以创建另一个流。第三个流将是 Student 个对象的流。我们生成每个 Student 对象,方法是获取该行的三个部分,将第 2 部分和第 3 部分解析为 int 值,并将所有 3 个输入到我们的 Student 记录的构造函数中。结果是 Student,一个接一个的学生对象,形成第三个流。

最后,我们将第三个流产生的 Student 个对象收集到一个列表中。

List < Student > students =
        input
                .lines()                            // First stream, of `String` objects, one for each line in our source text.
                .map( line -> line.split( "," ) )   // Second stream, of `String[]` objects. 
                .map( lineParts ->                  // Third stream, of `Student` objects produced by the three parts of each line of input text.
                        new Student(
                                lineParts[ 0 ] ,
                                Integer.parseInt( lineParts[ 1 ] ) ,
                                Integer.parseInt( lineParts[ 2 ]
                                )
                        )
                )
                .toList();

您的目标是更改每个学生的年龄。要使用不可变对象(记录)做到这一点,我们可以定义一个方法,该方法 returns 基于原始值的新对象。所以我们添加一个withAge方法。我们使用单词 with per naming conventions established by the java.time classes.

record Student( String name , int id , int age )
{
    Student withAge ( int age ) { return new Student( this.name , this.id , age ); }
}

修改年龄。

List < Student > results = new ArrayList <>( students.size() );
for ( int i = 0 ; i < students.size() ; i++ )
{
    Student student = students.get( i );
    results.add( student.withAge( i ) );
}

这是整个示例 class,为了您 copy-paste 方便。

package work.basil.example.text;

import java.util.ArrayList;
import java.util.List;

public class App
{
    public static void main ( String[] args )
    {
        App app = new App();
        app.demo();
    }

    private void demo ( )
    {
        String input =
                """
                Josh,2134,19
                Smith,5256,21
                Rogers,9248,19
                Andrew,7742,20     
                """;

        record Student( String name , int id , int age )
        {
            Student withAge ( int age ) { return new Student( this.name , this.id , age ); }
        }

        List < Student > students =
                input
                        .lines()
                        .map( line -> line.split( "," ) )
                        .map( lineParts ->
                                new Student(
                                        lineParts[ 0 ] ,
                                        Integer.parseInt( lineParts[ 1 ] ) ,
                                        Integer.parseInt( lineParts[ 2 ]
                                        )
                                )
                        )
                        .toList();

        List < Student > results = new ArrayList <>( students.size() );
        for ( int i = 0 ; i < students.size() ; i++ )
        {
            Student student = students.get( i );
            results.add( student.withAge( i ) );
        }

        System.out.println( "students = " + students );
        System.out.println( "results = " + results );
    }
}

当运行.

students = [Student[name=Josh, id=2134, age=19], Student[name=Smith, id=5256, age=21], Student[name=Rogers, id=9248, age=19], Student[name=Andrew, id=7742, age=20]] results = [Student[name=Josh, id=2134, age=0], Student[name=Smith, id=5256, age=1], Student[name=Rogers, id=9248, age=2], Student[name=Andrew, id=7742, age=3]]