ChefCurry
ChefCurry

Reputation: 45

Accessing specific elements in Arraylist of Objects

Really confused on how to access just the age of a specific student where all the information of students have been stored in a textfile. I am reading the textfile and storing that info into a student object, just need help on accessing this.

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;
    }
}

My Text File looks something like this: This info is stored in parallel array lists. I don't quite get how to implement this into an object to pass it into my second contractor method.

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

Here's what I've tried;

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

The only way I think of fixing this is to read the file 3 times to store the names, idnum, and ages in seperate arraylists. And then use that separate array list to store the age using ageList.get(i). I beleive that would be super uneccessary??

Upvotes: 2

Views: 1102

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338211

The Answer by davidalayachew looks correct. For fun, here is an alternative.

Streams

Provide input data. I will simulate a file with a String as textual input.

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

Define a Student class to hold data. If the main purpose of this class is to transparently and immutable communicate data, use a record. The compiler implicitly creates the constructor, getters, equals & hashCode, and toString.

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

Note that we can declare a record locally, within a method. Or declare nested in another class, or separately on its own.

Next we do a bunch of work in a single statement by using streams.

First we make a stream of each line in our input text. By calling String#lines, we get a Stream< String >, a series of elements of type String.

For each one of those lines, we call Stream#map to create another stream. We split each line by COMMA character to get a string arrays, String[]. Each array has three elements, the three pieces of info in each line.

For each string array of line parts, we call Stream#map yet again to make yet another stream. This third stream will be a stream of Student objects. We produce each Student object by taking the three parts of the line, parsing the 2nd and 3rd into int values, and feeding all 3 into the constructor of our Student record. The result is a Student, one student object after another, forming a third stream.

Lastly, we collect the Student objects produced by that third stream into a list.

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();

Your goal is to change the age of each student. To do that with immutable objects (records), we can define a method that returns a new object based on values from the original. So we add a withAge method. We use the word 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 ); }
}

Make your modified ages.

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 ) );
}

Here is that entire example class, for your copy-paste convenience.

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 );
    }
}

When run.

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]]

Upvotes: 1

davidalayachew
davidalayachew

Reputation: 1553

You can chain methods together like this.

      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());
         }
      }

Here, I chained users.get(i) to get the Student at index i, then I call getIdNum(), which fetches the ID from that Student that I just fetched.

Then, I perform a == comparison --> Is the ID that the user entered the same as the ID from this particular Student I am looking at?

If the result is true, then I call users.get(i) again, which fetches that same Student again, and then I store that into a temporary Student variable called temp. temp is now referencing that Student on the ArrayList that passed the ID check.

Then, I take temp, and use the getIdNum() and getAge() methods that it has (because temp is an instance of Student, and Student has those methods), and use them to create a message that I print onto the command line.

Here is a complete, runnable example.

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

}

Upvotes: 2

Related Questions