Copying arrays in Java
Arrays.copyOf, System.arraycopy, clone() — shallow copies.
Three real copiers
Unlike b = a, these create separate arrays: **a.clone() (same length and elements), Arrays.copyOf(a, n) (a new array of length n, padded with defaults or cut short), and System.arraycopy** (copies a range into an existing array). For an int[], changing the copy never affects the original.
int[] a = {1, 2, 3};
int[] b = a.clone(); // [1,2,3]
int[] c = Arrays.copyOf(a, 5); // [1,2,3,0,0]
int[] d = Arrays.copyOf(a, 2); // [1,2]Grow and shrink
What prints?
int[] a = {4, 5, 6};
int[] big = Arrays.copyOf(a, 5);
int[] small = Arrays.copyOf(a, 2);
String s1 = Arrays.toString(big);
String s2 = Arrays.toString(small);
System.out.println(s1 + s2);[4, 5, 6, 0, 0][4, 5][4, 5, 6][4, 5][4, 5, 6, 0, 0][5, 6]
Show the answer
copyOf with a bigger length pads the extra slots with the default 0. With a smaller length it keeps the first elements and cuts the rest.
System.arraycopy
System.arraycopy(src, srcPos, dest, destPos, count) copies count elements starting at src[srcPos] into an existing array, starting at dest[destPos]. Everything else in dest is left as it was.
int[] src = {1, 2, 3, 4, 5};
int[] dst = new int[5];
System.arraycopy(src, 1, dst, 0, 3);
// dst: [2, 3, 4, 0, 0]Your turn
What prints?
int[] src = {1, 2, 3, 4, 5};
int[] dst = new int[5];
System.arraycopy(src, 3, dst, 1, 2);
System.out.println(Arrays.toString(dst));[0, 4, 5, 0, 0][4, 5, 0, 0, 0][0, 3, 4, 0, 0][0, 0, 0, 4, 5]
Show the answer
Copy 2 elements starting at src[3] (4 and 5) into dst starting at index 1. The other slots keep their 0s.
Shallow copies
All three copiers are shallow: they copy each element's value. For an array of objects, or the rows of a 2-D array, that value is a reference, so both arrays end up sharing the same objects. Writing *into* a shared row shows up in both.
int[][] grid = {{1, 2}, {3, 4}};
int[][] copy = grid.clone();
copy[0][0] = 99; // grid[0][0] is 99 too!Shared rows
What prints?
int[][] g = {{1, 2}, {3, 4}};
int[][] c = g.clone();
c[1][1] = 0;
c[0] = new int[]{9, 9};
System.out.println(g[0][0] + " " + g[1][1]);1 09 01 49 4
Show the answer
c[1][1] = 0 writes into row 1, which both arrays share, so g[1][1] is 0. But c[0] = new int[]{9, 9} replaces a row in c only; g[0] still points to {1, 2}.
Deep copy by hand
To fully copy a 2-D array, copy the outer array and every row. Otherwise your "backup" changes whenever the original does.
int[][] copy = new int[grid.length][];
for (int r = 0; r < grid.length; r++) {
copy[r] = grid[r].clone();
}In real projects
Undo history, game AI that tries moves on a copy of the board, snapshots of settings: all need copies that are truly independent. Shallow copies of nested data are a classic source of "ghost" bugs, where changing one thing mysteriously changes another.
Key takeaways
- Arrays.copyOf can also grow (padding with defaults) or shrink
- System.arraycopy copies a range into an existing array
- clone() returns a new array with the same length and elements
- Shallow: object elements and inner arrays are shared, not duplicated
System.arraycopy even handles overlapping ranges within the same array correctly: it behaves as if the source range were first copied to a temporary array.
Practice questions
What does this print?
int[] a = {1, 2, 3};
int[] b = Arrays.copyOf(a, 5);
b[0] = 9;
System.out.println(Arrays.toString(b) + " " + a[0]);- [9, 2, 3] 1
- [9, 2, 3, 0, 0] 9
- [9, 2, 3, 0, 0] 1
- Throws ArrayIndexOutOfBoundsException
Check your answer
[9, 2, 3, 0, 0] 1. copyOf with a bigger length pads the extra slots with 0. b is a separate array, so a[0] stays 1.
What does this print?
int[] src = {1, 2, 3, 4, 5};
int[] dst = new int[5];
System.arraycopy(src, 1, dst, 0, 3);
System.out.println(Arrays.toString(dst));- [1, 2, 3, 0, 0]
- [2, 3, 4, 0, 0]
- [0, 2, 3, 4, 0]
- [2, 3, 4, 5, 0]
Check your answer
[2, 3, 4, 0, 0]. It copies 3 elements starting at src[1] (2, 3, 4) into dst starting at index 0. The rest of dst keeps its default 0s.