-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.

RMachnik
  • 3,598
  • 1
  • 34
  • 51
batool_42
  • 13
  • 1
  • 7

5 Answers5

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);
  }
}
Jerry101
  • 12,157
  • 5
  • 44
  • 63
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.

aliteralmind
  • 19,847
  • 17
  • 77
  • 108
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);
    }
RMachnik
  • 3,598
  • 1
  • 34
  • 51
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.

Tyler Durden
  • 11,156
  • 9
  • 64
  • 126
  • "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. – aliteralmind Feb 28 '14 at 19:22
  • 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. – Tyler Durden Feb 28 '14 at 19:35
  • 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()`. – aliteralmind Feb 28 '14 at 19:42
  • And if the protected versions are visible in your JavaDoc, they are easily documented as well. – aliteralmind Feb 28 '14 at 19:43
  • "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. – aliteralmind Feb 28 '14 at 19:56
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];
}
Markus Millfjord
  • 707
  • 1
  • 6
  • 26