简体   繁体   中英

How can I add mulitple items to an ArrayList without using Arrays

I'm learning Java and trying out stuff. I want to be able to print students' names with their courses and grades. I have written the following classes to achieve that but since I'm a newbie, I'm wondering if I have done it correctly. The code does display what I want but how can I best optimize it?

Subject class:

public class Subject {

    private String subjName;
    private int subjGrade;

    public Subject(String subjName, int subjGrade) {
       this.subjName = subjName;
       this.subjGrade = subjGrade;
    }

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

    public String getName() {
        return subjName;
    }
    public int getGrade(){
        return subjGrade;
    }

    @Override
    public String toString() {
        return String.format( getName() + ", Grade:" + getGrade());
    }
}

StudentSubJGrade class:

import javax.swing.text.html.HTMLDocument;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

public class StudentSubJGrade {

    String name;
    Subject[] subjects;

    public String getName() {
        return name;
    }

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

    public void setSubjects(Subject[] subjects) {
        this.subjects = subjects;
    }

    public StudentSubJGrade(String name, Subject[] subjects) {
        this.name = name;
        this.subjects = subjects;
    }

    @Override
    public String toString() {
        return String.format("Name:" + getName() + " Subjects:" +   Arrays.toString(subjects));
    }
}

I feel I can add the subjects via the ArrayList but couldn't come up with how to do it after hours of trials. How can this be done without using arrays as I have done?

Driver class:

import java.util.ArrayList;

public class StudentSubjGradeDriver {

    public static void main(String[] args) {

        ArrayList<StudentSubJGrade> test = new ArrayList<>();
        ArrayList<StudentSubJGrade> test2 = new ArrayList<>();

        Subject[] subjects = new Subject[3];
        subjects[0] = new Subject("Maths",80);
        subjects[1] = new Subject("Physic",90);
        subjects[2] = new Subject("Chemistry",70);

        Subject[] subjects1 = new Subject[4];

        subjects1[0] = new Subject("Maths",80);
        subjects1[1] = new Subject("Physic",90);
        subjects1[2] = new Subject("Chemistry",70);
        subjects1[3] = new Subject("Geography",90);

        test.add(new StudentSubJGrade("Anita",subjects));
        test2.add(new StudentSubJGrade("James",subjects1));   

        System.out.println(test);
        System.out.println(test2);    
    }
}

After carrying out suggestions, I tried improving on the code by creating the subjects as ArrayLists but I'm having trouble with it:

ArrayList<Subject> subjects;


public StudentSubJGrade(String name, ArrayList<Subject> subjects) {
    this.name = name;
    this.subjects = subjects;
}

Now in the main method, I tried the following but I'm getting an error:

ArrayList<StudentSubJGrade> test = new ArrayList<>();
ArrayList<Subject> st = new ArrayList<>();
st.add(new Subject("Maths",90));
test.add("Anita",st);

The problems with your code are that a) you are passing an array to the constructor without copying it, and b) you cannot change the subjects later.

For example, for a) say that you do the following:

    Subject[] subjects = new Subject[] {
        new Subject("Maths",80),
        new Subject("Physic",90),
        new Subject("Chemistry",70),
        new Subject("Geography",90)
    };

    StudentSubJGrade student = new StudentSubJGrade("Hassan", subjects );

So far, so good. But now:

    subjects[ 0 ] = null;

And suddenly your StudentSubJGrade student object has a null in its subjects.

This effect has to do with arrays being objects (like Student ), instead of value types (as in int x = 5 ), which implies that in your case both references will point to the same array.

Take look here for a demo on shared array objects .

You can avoid this by changing the method setSubjects() .

public void setSubjects(Subject[] subjects)
{
    this.copySubjects( subjects );
}

private void copySubjects(Subject[] subjects)
{
    final int arraySize = subjects.length;

    this.subjects = new Subject[ arraySize ];
    System.arraycopy( subjects, 0, this.subjects, 0, arraySize );
}

public StudentSubJGrade(String name, Subject[] subjects) {
    this.name = name;
    this.copySubjects( subjects );
}

If you need to change the subjects later, then you need to change the array inside the class for an ArrayList , and never expose it. You can get the subjects with the toArray() method, and accept an array or an enumeration to load it.

public void clearSubjects()
{
    this.subjects.clear();
}

public void addSubjects(Subject[] subjects)
{
    this.appendSubjects( subjects );
}

private void appendSubjects(Subject[] subjects)
{
    this.subjects.addAll( subjects );
}

public Subject[] getSubjects()
{
    return this.subjects.toArray( new Subject[ 0 ] );
}

public StudentSubJGrade(String name, Subject[] subjects)
{
    this.name = name;
    this.appendSubjects( subjects );
}

private ArrayList<Subject> subjects;

Hope this helps.

You have to use arrays because the StudentSubJGrade constructor expects the second argument to be a Subject[] . However, you can simplify your creation of the arrays:

import java.util.ArrayList;

public class StudentSubjGradeDriver {

    public static void main(String[] args) {

        ArrayList<StudentSubJGrade> test = new ArrayList<>();
        ArrayList<StudentSubJGrade> test2 = new ArrayList<>();

        Subject[] subjects = new Subject[] {
            new Subject("Maths",80),
            new Subject("Physic",90),
            new Subject("Chemistry",70)
        };

        Subject[] subjects1 = new Subject[] {
            new Subject("Maths",80),
            new Subject("Physic",90),
            new Subject("Chemistry",70),
            new Subject("Geography",90)
        };

        test.add(new StudentSubJGrade("Hassan",subjects));
        test2.add(new StudentSubJGrade("James",subjects1));   

        System.out.println(test);
        System.out.println(test2);    
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM