0

First part is:

public class Lab2 {
   public static void main(String[]args) throws Exception {
        Train train1 = new Train(3);
        Train train1Copy = train1.clone();
        train1Copy.carriages[0][0] = 5125;

        System.out.println("train1")
        System.out.println("Copyed");
        ... ...
    }}

Train is:

public class Train implements Cloneable {
    private int petrol, bananas, coal, grains, fertilizers;
    // количество вагонов, и груз в них
    int[][] carriages;

    public Train(int numOfCarriages) {
        carriages = new int[numOfCarriages][5];
        for (int i=0; i<numOfCarriages; i++) {
            petrol = (int)Math.round(Math.random() * 13);
            ... ...
            carriages[i][0] = petrol;
            ... ...
        }
    }

    @Override
    public Train clone() throws CloneNotSupportedException {
        return (Train) super.clone();
    }
    public String getPetrol() {
        String petrolText = "";
        for (int i=0; i<carriages.length; i++) {
             petrolText += i+1 + " carriage petrol= " + carriages[i][0] + "\n";
        }
        return petrolText;
    }
}

As I think, there could be some problems caused by constructor. And what I got in console is:

train1
1 carriage petrol= 5125
2 carriage petrol= 1
3 carriage petrol= 8


Copyed
1 carriage petrol= 5125
2 carriage petrol= 1
3 carriage petrol= 8

I watched some guides how to clone objects and as I see, my clone method is the same

Nikita Shadkov
  • 372
  • 3
  • 11
  • 1
    Clone performs a shallow copy. That means the clone references the same `carriages` array as the original, unless you add some code to copy it to your overridden clone method. – khelwood Feb 26 '20 at 07:02
  • 1
    You must implement clone() to create a fresh array for `carriages`. I believe reading this difference would helpful [Shallow Copy vs Deep Copy](https://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy). – rahulkesharwani Feb 26 '20 at 07:10
  • See also [copy a 2d array in Java](https://stackoverflow.com/questions/1686425/copy-a-2d-array-in-java) – khelwood Feb 26 '20 at 07:16
  • Guys, thank you very much. I just made it in 2 ways. The second one is creating a new array and simply copying in it. – Nikita Shadkov Feb 26 '20 at 12:46

3 Answers3

1

If we want to create a deep copy of object X and place it in a new object Y then new copy of any referenced objects fields are created and these references are placed in object Y. This means any changes made in referenced object fields in object X or Y will be reflected only in that object and not in the other. In below example, we create a deep copy of object. A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy occurs when an object is copied along with the objects to which it refers.

// A Java program to demonstrate deep copy 
// using clone() 
import java.util.ArrayList; 

// An object reference of this class is 
// contained by Test2 
class Test 
{ 
    int x, y; 
} 


// Contains a reference of Test and implements 
// clone with deep copy. 
class Test2 implements Cloneable 
{ 
    int a, b; 

    Test c = new Test(); 

    public Object clone() throws
                CloneNotSupportedException 
    { 
        // Assign the shallow copy to new reference variable t 
        Test2 t = (Test2)super.clone(); 

        t.c = new Test(); 

        // Create a new object for the field c 
        // and assign it to shallow copy obtained, 
        // to make it a deep copy 
        return t; 
    } 
} 

public class Main 
{ 
    public static void main(String args[]) throws
                            CloneNotSupportedException 
    { 
    Test2 t1 = new Test2(); 
    t1.a = 10; 
    t1.b = 20; 
    t1.c.x = 30; 
    t1.c.y = 40; 

    Test2 t3 = (Test2)t1.clone(); 
    t3.a = 100; 

    // Change in primitive type of t2 will not 
    // be reflected in t1 field 
    t3.c.x = 300; 

    // Change in object type field of t2 will not 
    // be reflected in t1(deep copy) 
    System.out.println(t1.a + " " + t1.b + " " + 
                        t1.c.x + " " + t1.c.y); 
    System.out.println(t3.a + " " + t3.b + " " + 
                        t3.c.x + " " + t3.c.y); 
    } 
} 
SandOfTime
  • 692
  • 6
  • 15
  • 1
    Do you propose to create another class with _"carriage"_ array? Cause in your example there will be empty _"t3.c.x and t3.c.y"_ . So if you copy it that way: _"t.c = new Test(); "_ you just will get 0 in this variables – Nikita Shadkov Feb 26 '20 at 12:17
  • I see you have already got the answer bellow, your Int array behave as a object not a primitive type so you needed to create a new array – SandOfTime Feb 27 '20 at 05:58
0

I just solved it with using Serializable implement:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream ous = new ObjectOutputStream(baos);
        ous.writeObject(train1);
        ous.close();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);

        Train train1Copy = (Train) ois.readObject();

My teacher said it will work, but it's not the best way to do it especially in big projects.

Nikita Shadkov
  • 372
  • 3
  • 11
0

Or it could be done this way:

@Override
    public Train clone() throws CloneNotSupportedException {
        Train train = (Train) super.clone();
        train.carriages = new int[carriages.length][5];
        for (int i=0;i<carriages.length;i++){
            for (int y=0; y<5; y++){
                train.carriages[i][y] = carriages[i][y];
            }
        }
        return train;
    }
Nikita Shadkov
  • 372
  • 3
  • 11