12 Replies Latest reply: Oct 31, 2007 11:08 AM by 3004 RSS

    How to copy an array of objects ? using 'System.arraycopy' -newbee question

    807600
      Hello!

      Trying to copy an array of objects, but it does just create a reference to the source-array - howcome ?

      Did create an Array of int :

           
         int []sourceArray = {1,2,3,4,5,6,7,8,9,10,11,12,13};
                int []targetArray = new int[ sourceArray.length ];
                System.out.println("Source:: "+sourceArray[0]);
                System.arraycopy(sourceArray, 0, targetArray, 0, sourceArray.length);
                targetArray[0]=99;
                System.out.println("target:: "+targetArray[0]);
                System.out.println("Source:: "+sourceArray[0]);
      And the output is what I expect:
      Source:: 1
                     target:: 99
                     Source:: 1
      Wanting to create several Person-object ( see class below ) and place them into a source-array and take a copy of
      that array - I then want to make changes to the copy without the changes affecting the source-array.

      public class Person {
      
           private int year;
           private String name;
      
           public Person(int year, String name) {
                this.year = year;
                this.name = name;
           }
      
           public int getYear() {
                return year;
           }
      
           public void setYear(int year) {
                this.year = year;
           }
      
           public String getName() {
                return name;
           }
      
           public void setName(String name) {
                this.name = name;
           }
           @Override
           public String toString() {
                return this.name +" " + this.year;
           }
           
      } 
      Here is the code that takes the copy of the Person-class.
       Person [] students = new Person [2];
                students[0]= new Person(1968,"James Gosling");
                System.out.println("Source "+students[0]);
                Person [] copyStudents = new Person [2];
                
                System.arraycopy(students, 0, copyStudents, 0, students.length);          
                copyStudents[0].setYear(1955);          
                System.out.println("Target "+copyStudents[0]);
                System.out.println("Source "+students[0]);
      And the output is NOT what I expect:
      Source namnet ?r: James Gosling och f?delse?r 1968
      Target namnet ?r: James Gosling och f?delse?r 1955
      Source namnet ?r: James Gosling och f?delse?r *1955*

      The last output should still be 1968.
      So why is the Source-array affected at all ?
      How do I make a copy of an array with objects ?

      regards, i
        • 1. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
          807600
          but it does just create a reference to the source-array - howcome ?
          You have to clone each Person object in the array before you copy it. Override Object's clone() method in your Person class to create a deep clone.
          • 2. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
            807600
            I do find this tutorial, but it is not that helpful.

            http://java.sun.com/developer/JDCTechTips/2001/tt0904.html

            So what should I do within my 'Person'-class ?
            What should I write within my Person ?

                 @Override
                 protected Object clone() {
                      // TODO Auto-generated method stub
                      return this;
                 }

            regards, i
            • 3. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
              807600
              What happens is in the first place for the student's variable this.year is set to 1968 while invoking Person(1968,"James Gosling");

              Next while invoking copyStudents[0].setYear(1955); the variable this.year is set to 1955. Now the value of the variable year is 1955 for both the students and copyStudents.
              • 4. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
                807600
                FebTen:
                'Now the value of the variable year is 1955 for both the students and copyStudents.'

                I am just changing the object within my copied-array, not wanting to change the object
                in my source-array.
                I want my copy to be 1955, but I want my source to still be 1968 - the source should not
                be affected when changing the copy. That is the reason for this thread, how do I create a copy of
                an array that contains objects.

                regards, i
                • 5. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
                  807600
                  public Object clone()
                  {
                  return new Person(year, name);
                  }
                  Now, I dont think you will be able to use System.arrayCopy
                  You need to create an array the same size as the one to be cloned, then:
                  for each
                      create a clone of that object
                      add that clone to the new array
                  then you have successfully copied your array of objects
                  • 6. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
                    807600
                    Do mean that I could do the following:

                         
                         Person [] copy = new Person[students.length];
                              int ii = 0;
                              for (Person person: students){
                                   System.out.println("Again "+person);
                                   copy[ii] = person;
                                   System.out.println("cc  "+copy[ii]);
                                   ii++;
                              }
                              copy[0].setName("GUSH");
                              System.out.println("Copy who? "+copy[0]);
                              System.out.println("Source who? "+students[0]);
                    after adding the following this code to my Person-class ?

                         @Override
                         protected Object clone() {
                              // TODO Auto-generated method stub
                              return this;
                         }

                    regards
                    • 8. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
                      807600
                      do you have an example that is working ?

                      regards, i
                      • 9. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
                        baftos
                        I see from other threads that you know C and perhaps C++.
                        I will try to explain you in C/C++ terms.
                        When you create an "array of objects", you only create an array
                        of references to objects. The objects themselves have not been
                        created yet; the array is populated with nulls.
                        In C jargon, you create an array of pointers to objects, all of
                        them initially NULL.
                        System.arraycopy() will copy the array of references (pointers),
                        therefore you have now 2 arrays populated with identical pointers,
                        but there is only one set of objects they point to. Therefore,
                        if you want a deep copy, you need to create a clone of each
                        original object and stick it into the second array. This is usually
                        accomplished by calling clone(). In your clone(), you propose
                        to 'return this'. You can see why this is wrong. You still
                        return a pointer to the original object, but what you want is
                        to crate a new object inside clone(), populate it field by field
                        from the 'this' fields and return a pointer to it.
                        If you check the Object.clone() and Clonable documnetation you
                        will see that this copying of fields from the old object to the
                        new one does not have to be so tedious, as Object itself
                        provides the basic functionality for shallow copying.

                        And by the way, reply #5 shows you the correct clone() implementation.

                        Edited by: baftos on Oct 31, 2007 10:32 AM
                        • 10. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
                          807600
                          InkiPin wrote:
                          Do mean that I could do the following:

                               
                               Person [] copy = new Person[students.length];
                                    int ii = 0;
                                    for (Person person: students){
                                         System.out.println("Again "+person);
                                         copy[ii] = person;
                                         System.out.println("cc  "+copy[ii]);
                                         ii++;
                                    }
                                    copy[0].setName("GUSH");
                                    System.out.println("Copy who? "+copy[0]);
                                    System.out.println("Source who? "+students[0]);
                          after adding the following this code to my Person-class ?

                               @Override
                               protected Object clone() {
                                    // TODO Auto-generated method stub
                                    return this;
                               }

                          regards
                          not exactly.
                          Try this:
                          Person [] copy = new Person[students.length];
                                    int ii = 0;
                                    for (Person person: students){
                                         System.out.println("Again "+person);
                                         copy[ii] = (Person)person.clone();
                                         System.out.println("cc  "+copy[ii]);
                                         ii++;
                                    }
                                    copy[0].setName("GUSH");
                                    System.out.println("Copy who? "+copy[0]);
                                    System.out.println("Source who? "+students[0]);
                          
                          
                          //IN your person class
                          public Object clone()
                          {
                            return new Person( this.year, this.name );
                          }
                          Now things should work like you want.
                          • 11. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
                            807600
                            I appreciate the effort.
                            But why not test the code and see if it is working first ?

                            regards, i
                            • 12. Re: How to copy an array of objects ? using 'System.arraycopy' -newbee ques
                              3004
                              InkiPin wrote:
                              I appreciate the effort.
                              But why not test the code and see if it is working first ?
                              Um, no. The burden is not on anyone here to test any code. All anybody here should be doing it giving you an idea of the approach you should take. Working out the details is your problem.