🧱 Arrays · Beginner

Copying arrays in Java

Arrays.copyOf, System.arraycopy, clone() — shallow copies.

🧩 The mysteryYou clone a 2D game board, make a move on the copy... and the original board changed too. Didn't you just copy it?

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]
🔮 Predict it

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);
  1. [4, 5, 6, 0, 0][4, 5]
  2. [4, 5, 6][4, 5]
  3. [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]
🔮 Predict it

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));
  1. [0, 4, 5, 0, 0]
  2. [4, 5, 0, 0, 0]
  3. [0, 3, 4, 0, 0]
  4. [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!
🔮 Predict it

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. 1 0
  2. 9 0
  3. 1 4
  4. 9 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}.

⚠️ The trap

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 the real world

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

  1. Arrays.copyOf can also grow (padding with defaults) or shrink
  2. System.arraycopy copies a range into an existing array
  3. clone() returns a new array with the same length and elements
  4. Shallow: object elements and inner arrays are shared, not duplicated
🤯 Did you know?

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]);
  1. [9, 2, 3] 1
  2. [9, 2, 3, 0, 0] 9
  3. [9, 2, 3, 0, 0] 1
  4. 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. [1, 2, 3, 0, 0]
  2. [2, 3, 4, 0, 0]
  3. [0, 2, 3, 4, 0]
  4. [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.

Next: grids, tables and triangles. Arrays of arrays, where every row can have its own length.