Using a method to create objects

70 Views Asked by At

I have a question regarding creating object using a method, please see my code below:

import java.util.ArrayList;
import java.util.Scanner;

public class Student {
    private String name;
    private int age;
    private double avgTestScore;

    // Getters
    public String getName(){ return this.name; }
    public int getAge(){ return this.age; }
    public double getAvgTestScore(){ return this.avgTestScore; }

    // Setters
    public void setName(){ this.name = " "; }
    public void setAge(){ this.age = 0; }
    public void setAvgTestScore(){ this.avgTestScore = 0.0; }

    //Constructor
    public Student(String name, int age, double score){
        this.name = name;
        this.age = age;
        this.avgTestScore = score;
    }

    public static Student createStudent(){
        Scanner scanner = new Scanner(System.in);

        System.out.println("Please enter the student name");
        String studentName = scanner.next();

        System.out.println("Please enter the student age");
        int studentAge = scanner.nextInt();

        System.out.println("Please enter the student score average");
        double studentScore = scanner.nextDouble();
        
        Student student = new Student(studentName, studentAge, studentScore);
        return student;
    }

    public static void addStudent(ArrayList<Student> list, Student student){
        list.add(student);
        for (Student i : list){
            System.out.println(i.name);
            System.out.println(i.age);
            System.out.println(i.avgTestScore);
        }
    }

    public static void main(String[] args){
        ArrayList<Student> studentArrayList = new ArrayList<>();
        Student.addStudent(studentArrayList, createStudent());
        Student.addStudent(studentArrayList, createStudent());



    }
}

I tried to create an int variable that would increase everytime the method is called and use that as part of the object name, for example:

public static Student createStudent(){
        **int identif = 0;**

        Scanner scanner = new Scanner(System.in);

        System.out.println("Please enter the student name");
        String studentName = scanner.next();

        System.out.println("Please enter the student age");
        int studentAge = scanner.nextInt();

        System.out.println("Please enter the student score average");
        double studentScore = scanner.nextDouble();
        
        Student student+**identif** = new Student(studentName, studentAge, studentScore);
        identif++;
        return student;
    }

After I tried this I realised how stupid I was being. After, I tried to allow the user input a String using the scanner and use that as object name, also didn't work.

My questions:

  • When a student object is created in my programme, what would the object name be?
  • If I create consecutive students using the method, does each previous student object get overwritten?
  • How do I allow the user to choose the name of the object.

TIA

2

There are 2 best solutions below

1
On BEST ANSWER

To clarify your query, it seems you are referring to "variable name" when mentioning "object name". In java you cannot create a dynamically calculated variable name. The question is why would you want to do so? If you need to store multiple objects and be able to access them by some value (let's say a string), then you may use a Map<>, like @Malz pointed out. For example:

int identifier = 0;
final String keyPrefix = "Student";

Map<String, Student> studentMap = new HashMap<>();

studentMap.put(keyPrefix + identifier++, createStudent());

Then, you can access the object by calling:

studentMap.get("Student0");

Of course if you don't need to use String as a key, then it is better to use just Integers to avoid string concatenation.

Now, answering your questions directly:

When a student object is created in my programme, what would the object name be?

If you don't override the toString() method, the object name would be className@randomHash if the Student is an outer class. So, for example, this is a sample string that would be printed if you used the toString() method on Student, or if you pass a student object to System.out.println() method (the toString() method is then called implicitely): Student@378fd1ac.

If I create consecutive students using the method, does each previous student object get overwritten?

Yes, if you create a single variable, let's say Student student, and then assign different objects to it, then the previous object gets overwritten. If you don't have any pointer to that object (i.e., you cannot access it from any other variable), then the object will get automatically garbage collected after some time.

Student student = createStudent();
student = createStudent(); //the first student object is not accessible anymore, so it is going to be garbage collected.

How do I allow the user to choose the name of the object.

Let's clarify the terminology:

Student student = new Student()
/\                    /\
||                    ||
variable              object

You may have a single variable pointing to different objects over time. The variable has its name and it cannot be changed. The object, on the other hand, may have a name, as you call it. It is just a String that is returned by the toString() method. The method is called implicitly when you try to print the object to the console, concatenate a string to it etc. For example having such class:

class Student {
    private final String name;

    Student(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student " + name;
    }
}

The System.out.println(new Student("Mark")) would yield Student mark

0
On

Here is a method with HashMap, where the input name serves as the designated key for the HashMap.

Code

Student.java

import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Map;
import java.util.Scanner;

/**
 * Represents a student with a name, age, and average test score.
 */
public class Student {
    private static Map<String, Student> students = new HashMap<>();

    private String name;
    private int age;
    private double avgTestScore;

    /**
     * Constructs a new Student object with the specified name, age, and average
     * test score.
     *
     * @param name         the name of the student
     * @param age          the age of the student
     * @param avgTestScore the average test score of the student
     */
    public Student(String name, int age, double avgTestScore) {
        this.name = name;
        this.age = age;
        this.avgTestScore = avgTestScore;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", avgTestScore=" + avgTestScore + "]";
    }

    /**
     * Creates a new Student object by taking input from the user.
     *
     * @return a new Student object created based on user input
     */
    public static Student create() {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Please enter the student name:");
        String studentName = scanner.next();

        int studentAge = 0;
        boolean validAgeInput = false;
        while (!validAgeInput) {
            try {
                System.out.println("Please enter the student age:");
                studentAge = scanner.nextInt();
                validAgeInput = true;
            } catch (InputMismatchException e) {
                System.out.println("Invalid input. Please enter a valid integer for age.");
                scanner.next();
            }
        }

        double studentScore = 0.0;
        boolean validScoreInput = false;
        while (!validScoreInput) {
            try {
                System.out.println("Please enter the student score average (delimeter : ','):");
                studentScore = scanner.nextDouble();
                validScoreInput = true;
            } catch (InputMismatchException e) {
                System.out.println("Invalid input. Please enter a valid double for score.");
                scanner.next();
            }
        }
        scanner.close();
        Student student = new Student(studentName, studentAge, studentScore);

        return student;
    }

    public static Map<String, Student> getStudents() {
        return students;
    }

    /**
     * Prints the details of the given student and adds it to the map of students.
     *
     * @param student the student to be added
     */
    public static void putStudent(Student student) {
        System.out.println("Name: " + student.getName());
        System.out.println("Age: " + student.getAge());
        System.out.println("Score: " + student.getAvgTestScore());

        students.put(student.getName(), student);
    }

    /**
     * Retrieves a student from the map based on the given key.
     *
     * @param key the key to retrieve the student
     * @return the student associated with the given key
     */
    public static Student getStudent(String key) {
        return students.get(key);
    }

    public static void setStudents(Map<String, Student> students) {
        Student.students = students;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getAvgTestScore() {
        return avgTestScore;
    }

    public void setAvgTestScore(double avgTestScore) {
        this.avgTestScore = avgTestScore;
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        Student student = Student.create();
        Student.putStudent(student);
        
        System.out.println(Student.getStudent("Max"));
    }
}

Input / Output

Please enter the student name:
Max
Please enter the student age:
24
Please enter the student score average (delimeter : ','):
1,2
Name: Max
Age: 24
Score: 1.2
Student [name=Max, age=24, avgTestScore=1.2]