tags:

views:

225

answers:

2

What is the difference between

  • System.arraycopy(),
  • clone()
  • manual copying by iterating through the elements
  • and just doing arraynew = arrayold?
+6  A: 
  • System.arraycopy() uses JNI (Java Native Interface) to copy an array (or parts of it), so it is blazingly fast, as you can confirm here;
  • clone() creates a new array with the same characteristics as the old array, i.e., same size, same type, and same contents. Refer to here for some examples of clone in action;
  • manual copying is, well, manual copying. There isn't much to say about this method, except that many people have found it to be the most performant.
  • arraynew = arrayold doesn't copy the array; it just points arraynew to the memory address of arrayold or, in other words, you are simply assigning a reference to the old array.
JG
That article about `arraycopy` was written in 2006. `clone` could (in theory, and should for obvious reasons) be specially treated by the runtime to perform exactly a `memcpy`. The `memcpy` is followed by a pass to clear the "lock" bit in the header of each array element. There's no reason why `arraycopy` and `clone` should perform differently.
280Z28
@me: The part about the lock bits is assuming you can lock on any object in Java like you can in .NET.
280Z28
+1. However, you could maybe clarify what a shallow copy is (e.g. *A clone of a multidimensional array is shallow, which is to say that it creates only a single new array. Subarrays are shared.*).
Pascal Thivent
@280Z28: `arraycopy` can be special-cased just the same as `clone`. @JG: *all* of those ways create shallow copies (except maybe manually copying, depending on how it's done).
Joachim Sauer
@Pascal: That's actually a jagged array as opposed to a true multidimensional array. A shallow copy of a true multidimensional array *should* be a shallow copy of the elements, not a shallow copy of the columns. (Java doesn't support multidimensional arrays so this never comes up.)
280Z28
@Joachim: `arraycopy` has unnecessary overhead due to initializing the elements of the target array followed by immediately writing back over them. `clone` should be the fastest because it wouldn't have to initialize memory. `cloneRange` would be fastest overall by allocating uninitialized memory and shallow copying an array subrange into it. All of the above should be implemented by the runtime itself, which means no JNI (lower than the JNI - the JIT could detect these calls and handle them with machine code).
280Z28
@280Z28: what you say about `arraycopy` only makes sense if you `arraycopy` into a newly created array. Of course that's not the right way to do it. But `arraycopy` is very useful if you want to copy from one existing array to another existing array. And what is `cloneRange` that you're talking about? `copyOf` does pretty much what the name of `cloneRange` would imply.
Joachim Sauer
@Joachim: The function is available as `copyOfRange`, which I assume `clone` and `copyOf` are special cases of. `arraycopy` to a previously created array is the other important case, but it can still be done faster than JNI.
280Z28
@Pascal and @Joachim: You are both right, I've updated my answer regarding `clone`.@280Z28: Java does support multidimensional arrays.
JG
@JG: Java doesn't support *really* multidimensional arrays. Multidimensional arrays in Java are just arrays of arrays (compare this to C where a multidimensional array is indeed a continuous block of memory).
Joachim Sauer
+3  A: 
  • System.arrayCopy() copies data from one existing array into another one and depending on the arguments only copies parts of it.
  • clone() allocates a new array that has the same type and size than the original and ensures that it has the same content.
  • manual copying usually does pretty much the same thing than System.arraycopy(), but is more code and therefore a bigger source for errors
  • arraynew = arrayold only copies the reference to the array to a new variable and doesn't influence the array itself

There is one more useful option:

Arrays.copyOf() can be used to create a copy of another array with a different size. This means that the new array can be bigger or larger than the original array and the content of the common size will be that of the source. There's even a version that makes it possible to create an array of a different type, and a version where you can specify a range of elements to copy (Array.copyOfRange()).

Note that all of those methods make shallow copies. That means that only the references stored in the arrays are copied and the referenced objects are not duplicated.

Joachim Sauer