• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

why does System.arraycopy() act like a for loop to copy one array's values to another if its shallow

 
Greenhorn
Posts: 3
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi guys i have read everywhere that this method is shallow but when i go to test it and change a value in one of the arrays, the other one is unaffected.
im really confused... maybe i'm confusing the terminology. i was taught to use a for loop to copy values, but i dont why not take advantage of System.arraycopy()?



output is:
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is a shallow copy. That means that the values (references or primitives) in one array are copied to the other array. And since it's shallow, not deep, that means that when copying references, it doesn't drill into the objects that the references point to.

When copying primitives as you are doing, there's no distinction between shallow and deep because there's no "drilling into" to be done.

Whether it's primitives or references, arraycopy has the same exact result as copying the elements yourself in a loop.
 
Steve Higgins
Greenhorn
Posts: 3
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi and ty for the reply. i guess i am still a bit confused.
if i code array1=array2 i understand that this is a shallow copy taking place too; or am i wrong?
but then when i change a value in array1, array2 is changed as well. but with arraycopy() this is not the case, but they are both shallow copy methods???

i guess this whole distinction between shallow and deep and what is really going on does not make sense to me.
i do appreciate your response though friend and ty again.
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In the case of array1 = array2, you aren't copying the array at all. You're copying the reference to it, but it's still referencing the same array.

Shallow copying an array generally means making a new array, but just making a simple copy of every value in it. Whereas a deep copy means following every reference to an object and recursively copying it completely.
 
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So is it correct when I say that the method of class TreeSet results in a subset which is a "deep" copy of the respective elements of the original set? Any changes we make to one will be reflected in the other. Because as you explained about deep copy, this does confirm to that definition. Am I correct?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mansukhdeep Thind wrote:So is it correct when I say that the method of class TreeSet results in a subset which is a "deep" copy of the respective elements of the original set? Any changes we make to one will be reflected in the other. Because as you explained about deep copy, this does confirm to that definition. Am I correct?



No. A deep copy is where you copy each field--or at least each mutable field--in each object, recursively, all the way down, so that changes made in one copy are NOT reflected in the other.

A shallow copy is where you only copy the "top layer" of values.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK. Could you perhaps provide me with a link where I can study these shallow and deep copy concepts in detail with examples for each?
 
Steve Higgins
Greenhorn
Posts: 3
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
me too. i think i need a visual drawing of wth is goign on.
thanks for the help guys but i still don't see the diff btwn for loop and arraycopy(). i mean is there soemthing that can go wrong if i use for loop vs arraycopy()?

after a for loop executes an array copy, is array1 still pointing to array1 and array2 still pointing to array2?
after arraycopy() executes an array copy, is array1 still pointing to array1 and array2 still pointing to array2?

i guess i am trying to find a difference soemwhere that i can comprehend.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mansukhdeep Thind wrote:OK. Could you perhaps provide me with a link where I can study these shallow and deep copy concepts in detail with examples for each?



I'm sure a web search will turn up plenty.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Steve Higgins wrote:
thanks for the help guys but i still don't see the diff btwn for loop and arraycopy().



Functionally they're the same. The difference is that arraycopy() could have an underlying native implementation that could take advantage of direct memory access calls that could be faster than anything you could write in Java. No guarantee that it will be, but it has that option.

mean is there soemthing that can go wrong if i use for loop vs arraycopy()?



Other than the general fact that there's always a chance we'll make a mistake when we write code, no. ;)

after a for loop executes an array copy, is array1 still pointing to array1 and array2 still pointing to array2?
after arraycopy() executes an array copy, is array1 still pointing to array1 and array2 still pointing to array2?



Yes, each reference variable still points to the same array object it originally did. And in both cases, assuming you wrote your for loop the "traditional" way, all the elements of one array have been copied into corresponding elements in the other array. So, for instance, if they're arrays of Date, then the reference in arr1[0] will point to the same Date object as the reference in arr2[0].

i guess i am trying to find a difference soemwhere that i can comprehend.



arraycopy() is less code for you to write, and could potentially be faster.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Steve Higgins wrote:me too. i think i need a visual drawing of wth is goign on.


Drawings are difficult in a text environment like this.

Just take it as already said, that arraycopy works exactly like a copy done with a loop.

The question is: what are you copying?

As said above, if you write array2 = array1, you are copying the reference of array1 to array2, so afterwards, the two variables will point to the same array. And if you write:you are doing exactly the same thing with each element, but the two arrays are separate copies.

Let's say now that each of those elements is a StringBuilder with the characters "Hello" in it, and you now write:what you will get is:
Hello World
because the two elements point to the same (mutable) object.

The only way you can separate the two objects completely is by cloning them, and that is what is meant by a "deep" copy.

HIH

Winston
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:
The only way you can separate the two objects completely is by cloning them, and that is what is meant by a "deep" copy.



I don't know if "clone" has a standard meaning of "deep copy" in CS in general, but the clone() method in the core API produces a shallow copy by default. (We can of course make it produce a deep copy in many cases, but that's not usually done, in my experience.)
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jeff Verdegan wrote:I don't know if "clone" has a standard meaning of "deep copy" in CS in general, but the clone() method in the core API produces a shallow copy by default.


True, which is why I didn't use clone(); but I couldn't think of another term that means "copy the entire memory footprint".

And when internal fields are immutable or primitive, it's not necessary anyway - however, that's probably a discussion for another time.

Winston
 
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I googled and the links I read all seemed poor quality.
 
Matthew Brown
Bartender
Posts: 4568
9
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't know how well this diagram will turn out on the forum, but hopefully it might help. Note that the "deep copy" still only shows one layer of copying - remember it potentially has to recurse into each object and copy any sub-objects.

So you should be able to see:

- If we've just copied the reference, any changes to one array are reflected in the second array (because they're actually the same array).
- With a shallow copy we can change one array without changing the other. But if we change any mutable objects referenced by one array that difference will be visible to the other because they are referencing the same objects.
- With a deep copy they are completely independent - changes to one data structure cannot affect the other.
arraycopy.png
[Thumbnail for arraycopy.png]
Array copies
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I googled and the links I read all seemed poor quality.


The best explanation I know of is in EJv2, Item 11, pp 54-61, even though it's basically a castigation of Cloneable in general.

Winston
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
EJv2 I presume is Bloch’s Effective Java™ 2nd edition.
That diagram came out well, Matthew. Thank you.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic