Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

clone() shallow copy in arrays?  RSS feed

 
Burkhard Hassel
Ranch Hand
Posts: 1274
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi ranchers,

I'm not sure about the difference of deep or shallow copies in multidimensional arrays.

The API says about Object' clone() method:
Note that all arrays are considered to implement the interface Cloneable. Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.



If the content of the fields are not themself cloned, why the following
clone() shallow copy in arrays?


Hi ranchers,

I'm not sure about the difference of deep or shallow copies in multidimensional arrays.

The API says about Object' clone() method:
Note that all arrays are considered to implement the interface Cloneable. Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.



If the content of the fields are not themself cloned, why the following


produces
<0,0><0,1><0,2>
<1,0><1,1><1,2>
----------------------------
<0,0><0,1><0,2>
<1,0><1,1><1,2>




Two times the same. Looks to me like a deep copy, rather than a shallow one. What am I misunderstanding?


Yours,
Bu.

--- edited the i tag
[ April 12, 2007: Message edited by: Burkhard Hassel ]
 
Campbell Ritchie
Marshal
Posts: 55681
161
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You will have to go back to your arrays, fill them with objects which override the Object.equals() method, and try again.
What it means by "shallow clone" is that the Object cloned is copied, but the fields are the same. So your second array is a copy of the first, but its members might be the same objects.
Suggest:-
  • Set up an array of arrays like that, but populated with objects.
  • Clone it.
  • Go through the two arrays and try whether "array1 == array2".
  • Go through the component arrays of your first array and again try whether "array1[0] == array2[0]".
  • Go through the individual members and see whether "array1[0][0] == array2[0][0]", and also whether "array1[0][0].equals(array2[0][0])"
  • Try that and tell us what happens That should show you what a shallow clone represents.
     
    Jim Yingst
    Wanderer
    Sheriff
    Posts: 18671
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Here's some more code you can try to see what happens:

    Which changes affect both arrays, and why?
     
    Burkhard Hassel
    Ranch Hand
    Posts: 1274
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi ranchers,

    thank you for guiding me, hope I got it now.

    In arrays, the references of the objects are copied, not the elements themselves, thus the output.

    I found also an easier way for me to understand this. And this goes without arrays.
    If you have an object that has an object (...) also only the references are copied. So just after the cloning, you have two objects, but they don't share the sub objects (sub here as HAS-A, not necessarily as IS-A) only through references.

    So the sub-objects are NOT distinct equal objects, only the references refer to the same original object(s).

    I included an example where class Cowboy has a Horse that has a Saddle. If I clone a Cowboy, the other one has the same Saddle, but when I change the Saddle in the original, the clone gets his Saddle changed as well.
    That's how I now understand "shallow copy".

    Interesting, even if all the subclasses (Horse, Saddle) implemement clone(), there will be no copied object of them,
    the code here is a bit long in the meanwhile, but:




    prints



    without arrays:
    b before:java.awt.Point[x=100,y=100]
    b after:java.awt.Point[x=100,y=100]

    Now ARRAYS:
    <0,0><0,1><0,2>
    <1,0><1,1><1,2>
    ----------------------------
    <0,0><0,1><0,2>
    <1,0><1,1><1,2>
    =================
    points==other:false
    points equals other:false
    points [0][0] == other[0][0]:true
    points [0][0] equals other[0][0]:true

    other[0][0] before:java.awt.Point[x=0,y=0]
    other[0][0] after:java.awt.Point[x=7,y=7]


    **************************
    And now Jim's:
    ----------------------------
    cloned points
    points:
    <0,0><0,1><0,2>
    <1,0><1,1><1,2>
    other:
    <0,0><0,1><0,2>
    <1,0><1,1><1,2>
    ----------------------------
    ----------------------------
    changed content of points[0][0]
    points:
    <-1,-1><0,1><0,2>
    <1,0><1,1><1,2>
    other:
    <-1,-1><0,1><0,2>
    <1,0><1,1><1,2>
    ----------------------------
    ----------------------------
    set points[0][1] to <-2,-2>
    points:
    <-1,-1><-2,-2><0,2>
    <1,0><1,1><1,2>
    other:
    <-1,-1><-2,-2><0,2>
    <1,0><1,1><1,2>
    ----------------------------
    ----------------------------
    set points[1] to empty array
    points:
    <-1,-1><-2,-2><0,2>

    other:
    <-1,-1><-2,-2><0,2>
    <1,0><1,1><1,2>
    ----------------------------



    At this point, the code becomes a bit long...
    leather in clone before: RAW_HIDE
    leather in clone after: FINE






    I made the clone methods using covariant return types, so Java 5.

    The beginning of main() shows that the cloned objects themself are independent (points a and b).


    Phew,
    Bu.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!