0

I am making a simple array of objects in Java, a portion of my code is the following

public class Student{
     private String name;
     private double score;
     public Student(String name){
        this.name=name;
        this.score=score
}

public class Classroom{
    private Student[] listStu;
    private int sc;
    public addStu(Student stu){
           listStu[sc]=stu;
           sc++;
    }
    public Student[] getClassroom(){
            return listStu;
    }
    public int getNum(){
           return sc;
    }
    public printList(){
          for (int i=0;i<sc;i++){
              System.out.pritnln(listStu[i].getName());
          }
}

and in the main class I program this:

Classroom c=new Classroom();
Student[] stuList;
int nStu;
Student s1=new Student("michael",3.0);
Student s2=new Student("larry",4.0);
c.addStu(s1);
c.addStu(s2);
stuList=c.getClassroom();
nStu=c.getNum();

the problem is when I modify an object of my class stuList in the main class, something like:

stuList[0].setName("peter");

I see when I call my printList method, that the data inside my array has also been modified (in my case the name of "michael" is changed by "peter"). The question that I have is how to make a copy of my array of objects into the stuList of the main class so that this array does not interfere with my original data? Is this procedure really necessary or is it unlikely this situation to happens?

Thanks

Little
  • 3,363
  • 10
  • 45
  • 74
  • passing arguments is key to java. Your call c.addStu() just passes a reference to your student-object. Therefore your object is still the same and it is absolutely not dependent which specific reference is used to do the actual object manipulation, the result will ever be the same, as there is only one object. Creating a copy of your object is a good way to solve your problem. Take a look at this article: http://en.wikipedia.org/wiki/Clone_%28Java_method%29 – Enno Jun 01 '13 at 21:53

5 Answers5

3

Normally you would use an List<Student> rather than writing your own collection, However the problem is the same. You have a shallow copy of the array which it appears you want a deep copy. Instead of taking a reference to the array you need to create a new array with new Student objects which contain the same information.

Obviously this is tedious and slow and the general recommendation is to avoid changing any collection (such as an array) you get from a collection. i.e. using the setName is a bad idea unless "Michael" has changed his name to "Peter". If you want to replace michael with Peter you have a enw Student and that should replace the old Student reference.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Make these changes to Student class:

class Student implements Cloneable {

    protected Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }

add this method in Classroom class:

public Student[] deepCopy() throws CloneNotSupportedException {
    Student[] deepCopy = new Student[this.listStu.length];
    for (Student student : this.listStu) {
        deepCopy[0] = student.clone();
    }
    return deepCopy;
}

and then this in the main method:

Student[] backupList = c.deepCopy();
backupList[0].setName("test");
System.out.println(backupList[0].getName());
System.out.println(stuList[0].getName());

will output:

test
michael

Also it seems you have some syntactic errors in code:

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

Missing close bracket } (the one from method), score is not a parameter, missing ;

But if you go with this solution, make sure you document yourself more about cloning in Java

user1236048
  • 5,542
  • 7
  • 50
  • 87
0

In Java you work with pointers, that's why, when you modify inside the second array, it does inside the first one too. Try changing this:

public addStu(Student stu){
       listStu[sc]=stu;
       sc++;
}

to this:

public addStu(Student stu){
       listStu[sc]=(Student) stu.clone();
       sc++;
}

and see if it works.

Alejandro Iván
  • 3,969
  • 1
  • 21
  • 30
0

For copying an array use System.arraycopy (see http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29).

But remember: an array of objects in Java is an array of references to the array's elements. Similar to cloning a collection, the copy will contain the same elements. For your use case you have to copy the elements itself.

mschenk74
  • 3,561
  • 1
  • 21
  • 34
0

You can simple do this:

Student newStudent = stuList[0];
newStudent.setName("peter");

Now you have a new object that if you change it the array values will not be affected.

kdureidy
  • 960
  • 9
  • 26