-2

How can I copy an object containing an array of other objects? Here is my copy constructor:

public university(university univ)    {
    String name1=univ.getname();
    int numOfPublications1=univ.getnumOfPublications(); 
    Department[] depts1 =new Department[numOfDepts];
    depts1=univ.getdepts();
}  

This is not working because the array is not there.

5
  • 2
    Format your code correctly, and you'll see why it doesn't compile. Commented Feb 28, 2014 at 19:10
  • copy the array docs.oracle.com/javase/6/docs/api/java/util/Arrays.html Commented Feb 28, 2014 at 19:15
  • @JBNizet why all the people till my that i have to format it ? is there is something wrong with it?? Commented Feb 28, 2014 at 19:31
  • 1
    Yes. Classes should have first letter in upper-case (university), methods should begin with small characters and then uppercase for each new "word" in it's name (getdepts), for starters. Commented Feb 28, 2014 at 19:51
  • @MarkusMillfjord thank you :) I will notice this next time . Commented Feb 28, 2014 at 22:06

5 Answers 5

0

Try doing this.

public university(university univ)    {
        String name1=univ.getname();
        int numOfPublications1=univ.getnumOfPublications(); 
        Department[] depts1 =new Department[numOfDepts];
        System.arrayCopy(univ.getdepts(),0,depts1,0,univ.getdepts().length);
//or this depts1 = Array.copyOf(univ.getdepts(),numOfDepts);
    }
Sign up to request clarification or add additional context in comments.

Comments

0

You can use System.arraycopy() to copy the contents of an array.

class University {
  Department[] departments;

  University(University toCopy) {
    departments = new Department[toCopy.departments.length];
    System.arraycopy(toCopy.departments, 0, departments, 0, departments.length);
  }
}

5 Comments

That creates a shallow copy though.
This will work if only a shallow copy of the array is needed (meaning each Department element does not need to be copied.).
True. If you need to copy the Department objects, write a loop that copies them one by one.
Or give Department a copy constructor, too.
Yes. To be clear for a novice, the loop will need to call Department's copy constructor.
0

Copy constructors have a lot of problems, and in general, cloning is preferable, but if you do want to use a copy constructor here is how:

public University( University univ ){
    University univ_copy = new University();
    univ_copy.name = univ.getname();
    univ_copy.numOfPublications = univ.getnumOfPublications();
    univ_copy.departments = new Department[univ.numOfDepartments];
    System.arrayCopy( univ.departments, 0, univ_copy.departments, 0, univ.departments.length );
    return univ_copy;
}

You can also copy the departments one by one, as opposed to copying them in one step with array copy. The key thing is that you need to allocate a new array for the copy, not re-use the existing array from univ because then you would not have a copy of the array, just a pointer to the original array.

5 Comments

"Copy constructors have a lot of problems, and in general, cloning is preferable". Can you elaborate? I have not had any problems with copy constructors.
One example of the kind of problem that can arise is when inheritance is involved. For example, if you had several different subclasses of University, then you would need different constructors for each one. Then you have the complexity of figuring out which constructor should be used. The essential problem is that the inheritance is determined at runtime, but a copy constructor is defined at compile time. Of course, there are ways to cope, but it can get confusing and awkward. For this reason, cloning is often easier to implement and debug.
If I'm understanding you, I disagree. The only thing you need to avoid in the constructor is calling public functions (that will be potentially overridden in sub-classes). For example, instead of calling public reset() from the constructor, have the constructor (and the public reset function) call protected resetMC() (where MC is an abbreviation for MyClass). Then sub-classes would have their own protected resetSC(), and their public reset()s would call super.reset() then resetSC().
And if the protected versions are visible in your JavaDoc, they are easily documented as well.
"Then you have the complexity of figuring out which constructor should be used." I don't understand. The constructor is implicit in the object you're copying, and it just calls its super-copy constructor. I don't see needing to figure anything out.
0

To deeply-copy the entire university class, including every element in the Department array, change this:

public university(university univ){
   ...
   Department[] depts1 =new Department[numOfDepts];
   depts1=univ.getdepts();
}

To this:

public university(university univ){
   ...
   depts1 =new Department[univ.depts1.length];
   for(int i = 0; i < univ.depts1.length; i++)  {
      depts[i] = new Department(univ.depts1[i]);
   }

}

This assume that your Department class also has a copy constructor.

Note that I have changed

Department[] depts = ...

to

depts = ...

If you don't do this, then the new depts array will stop existing at the end of your constructor.

Comments

0

Besides that you do not follow coding conventions, making your code completely unreadable, you should copy (which I assume you're trying to do, since you feed an instance of university argument to the university constructor) the departments instead of first creating an array of departments that you then immediately scrap and reassign the to argument's departments;

//Get departments from argument 
Department[] departments = univ.getdepts();

//Create your own local departments, if any
if (departments)
{
    this.departments = new Department[departments.length];

    //Copy, either cloned versions or references depending on what you want, for each and every cell in the argument university's department
    for (int i = 0; i < departments.length; i++)
        this.departments[i] = departments[i];
}

2 Comments

what do you mean by if (departments) , Is this legal code?
Yes, it's legal and mean "if defined", and will be true IFF there is an array defined (!= null), else false (== null)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.