如何不使用数组将多个项目添加到ArrayList

时间:2018-06-22 18:55:02

标签: java arraylist

我正在学习Java并尝试一些东西。我希望能够打印学生的姓名及其课程和成绩。我已经编写了以下课程来实现这一目标,但是由于我是新手,所以我想知道自己是否正确地做到了。该代码确实显示了我想要的内容,但是如何最好地对其进行优化?

Subject类:

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类:

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

我觉得我可以通过ArrayList添加主题,但经过数小时的尝试后仍无法提出如何做。不用像我一样使用数组怎么办?

驱动程序类:

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

提出建议后,我尝试通过将主题创建为ArrayLists来改进代码,但遇到了麻烦:

ArrayList<Subject> subjects;


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

现在在main方法中,我尝试了以下操作,但出现错误:

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

2 个答案:

答案 0 :(得分:2)

您的代码存在以下问题:a)您将数组传递给构造函数而不复制它,并且b)您以后无法更改主题。

例如,对于a),说您执行以下操作:

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

到目前为止,太好了。但是现在:

    subjects[ 0 ] = null;

突然,您的StudentSubJGrade 学生对象的对象中有一个null

此效果与数组是对象(例如 Student )而不是值类型(例如 int x = 5 )有关,这意味着在您的情况下这两个引用将指向同一数组。

在这里寻找demo on shared array objects

您可以通过更改方法 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 );
}

如果以后需要更改主题,则需要为 ArrayList 更改类内的数组,并且永远不要公开它。您可以使用 toArray()方法获取主题,并接受数组或枚举来加载它。

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;

希望这会有所帮助。

答案 1 :(得分:0)

您必须使用数组,因为StudentSubJGrade构造函数希望第二个参数为Subject[]。但是,您可以简化数组的创建:

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