Copying an array in java

In this post I show some ways to copy arrays of primitive data and objects to another array.

    • Copying a one-dimensional array of primitives: suppose you want to copy a one-dimensional array of integers named “a” in an array named “b”, the simple assignment
      b = a;
      

      doesn’t work.
      Consider the following code:

      public class Main {
      
          public static void main(String[] args) {
      
      	int[] a = { 1, 2, 3 };
      
      	int[] b = a;
      
      	System.out.println("b = " + printArray(b));
      
      	a[0] = 0;
      
      	System.out.println("b = " + printArray(b));
      
          }
      
          private static String printArray(int[] a) {
      	StringBuilder sb = new StringBuilder();
      	for (int i : a) {
      	    if (sb.length() == 0)
      		sb.append("{");
      	    else
      		sb.append(", ");
      	    sb.append(i);
      	}
      	sb.append("}");
      	return sb.toString();
          }
      }
      

      which has as output:

      b = {1, 2, 3}
      b = {0, 2, 3}
      

      It is clear that “a” and “b” point to the same object because the changes are reflected on the other one, this code does not assign a copy of the object pointed by “a” to “b”, it copies the reference of the same object.
      The following code creates a copy of “a” and assigns it to “b” using the static method System.arraycopy:

      public class Main {
      
          public static void main(String[] args) {
      
      	int[] a = { 1, 2, 3 };
      
      	int[] b = new int[3];
      
      	System.arraycopy(a, 0, b, 0, a.length);
      
      	System.out.println("b = " + printArray(b));
      
      	a[0] = 0;
      
      	System.out.println("b = " + printArray(b));
      
          }
      
          private static String printArray(int[] a) {
      	StringBuilder sb = new StringBuilder();
      	for (int i : a) {
      	    if (sb.length() == 0)
      		sb.append("{");
      	    else
      		sb.append(", ");
      	    sb.append(i);
      	}
      	sb.append("}");
      	return sb.toString();
          }
      }
      
      with output:
      b = {1, 2, 3}
      b = {1, 2, 3}
      

      It is also possible to copy the object by copying every single element within a loop.

    • Copy of multidimensional array of primitives: you can’t use System.arraycopy with multidimensional arrays but you have to assign each elements within a loop:
      public class Main {
      
          public static void main(String[] args) {
      
      	int[][] a = new int[3][4];
      
      	for (int i = 0; i < a.length; i++) {
      	    for (int j = 0; j < a[i].length; j++) {
      		a[i][j] = (i + 1) * 10 + j + 1;
      	    }
      	}
      
      	System.out.println("a =\n" + printArray(a));
      
      	int[][] b = new int[3][4];
      
      	for (int i = 0; i < a.length; i++) {
      	    for (int j = 0; j < a[i].length; j++) {
      		b[i][j] = a[i][j];
      	    }
      	}
      
      	for (int i = 0; i < a.length; i++) {
      	    for (int j = 0; j < a[i].length; j++) {
      		a[i][j] = 0;
      	    }
      	}
      	System.out.println("a =\n" + printArray(a));
      	System.out.println("b =\n" + printArray(b));
      
          }
      
          private static String printArray(int[][] a) {
      	StringBuilder sb = new StringBuilder();
      	for (int i = 0; i < a.length; i++) {
      	    for (int j = 0; j < a[i].length; j++) {
      		if (j > 0)
      		    sb.append("\t");
      		sb.append(a[i][j]);
      	    }
      	    sb.append("\n");
      	}
      	return sb.toString();
          }
      }
      

      with output:

      a =
      11	12	13	14
      21	22	23	24
      31	32	33	34
      
      a =
      0	0	0	0
      0	0	0	0
      0	0	0	0
      
      b =
      11	12	13	14
      21	22	23	24
      31	32	33	34
      

      In the case of a two-dimensional array, you can use System.arraycopy to assign an entire row inside a for loop:

      public class Main {
      
          public static void main(String[] args) {
      
      	int[][] a = new int[3][4];
      
      	for (int i = 0; i < a.length; i++) {
      	    for (int j = 0; j < a[i].length; j++) {
      		a[i][j] = (i + 1) * 10 + j + 1;
      	    }
      	}
      
      	System.out.println("a =\n" + printArray(a));
      
      	int[][] b = new int[3][4];
      
      	for (int i = 0; i < a.length; i++) {
      	    System.arraycopy(a[i], 0, b[i], 0, a[i].length);
      	}
      
      	for (int i = 0; i < a.length; i++) {
      	    for (int j = 0; j < a[i].length; j++) {
      		a[i][j] = 0;
      	    }
      	}
      	System.out.println("a =\n" + printArray(a));
      	System.out.println("b =\n" + printArray(b));
      
          }
      
          private static String printArray(int[][] a) {
      	StringBuilder sb = new StringBuilder();
      	for (int i = 0; i < a.length; i++) {
      	    for (int j = 0; j < a[i].length; j++) {
      		if (j > 0)
      		    sb.append("\t");
      		sb.append(a[i][j]);
      	    }
      	    sb.append("\n");
      	}
      	return sb.toString();
          }
      }
      
  • Copy of an array of objects: the above steps are about arrays of primitive, but here I want to copy an array of objects, in this case objects of the Point class.
    A first attempt might be this:

    import java.awt.Point;
    
    public class Main {
    
        public static void main(String[] args) {
    
    	Point[][] a = new Point[3][4];
    
    	for (int i = 0; i < a.length; i++) {
    	    for (int j = 0; j < a[i].length; j++) {
    		a[i][j] = new Point(i + 1, j + 1);
    	    }
    	}
    
    	System.out.println("a =\n" + printArray(a));
    
    	Point[][] b = new Point[3][4];
    
    	for (int i = 0; i < a.length; i++) {
    	    for (int j = 0; j < a[i].length; j++) {
    		b[i][j] = a[i][j];
    	    }
    	}
    
    	for (int i = 0; i < a.length; i++) {
    	    for (int j = 0; j < a[i].length; j++) {
    		a[i][j].setLocation(0, 0);
    	    }
    	}
    	System.out.println("a =\n" + printArray(a));
    	System.out.println("b =\n" + printArray(b));
    
        }
    
        private static String printArray(Point[][] a) {
    	StringBuilder sb = new StringBuilder();
    	for (int i = 0; i < a.length; i++) {
    	    for (int j = 0; j < a[i].length; j++) {
    		if (j > 0)
    		    sb.append("\t");
    		sb.append(a[i][j]);
    	    }
    	    sb.append("\n");
    	}
    	return sb.toString();
        }
    }
    

    but as you can see from the output:

    a =
    java.awt.Point[x=1,y=1]	java.awt.Point[x=1,y=2]	java.awt.Point[x=1,y=3]	java.awt.Point[x=1,y=4]
    java.awt.Point[x=2,y=1]	java.awt.Point[x=2,y=2]	java.awt.Point[x=2,y=3]	java.awt.Point[x=2,y=4]
    java.awt.Point[x=3,y=1]	java.awt.Point[x=3,y=2]	java.awt.Point[x=3,y=3]	java.awt.Point[x=3,y=4]
    
    a =
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    
    b =
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    

    doesn’t work because I don’t copy the element but the reference to the element at line 21.
    The correct code is:

    import java.awt.Point;
    
    public class Main {
    
        public static void main(String[] args) {
    
    	Point[][] a = new Point[3][4];
    
    	for (int i = 0; i < a.length; i++) {
    	    for (int j = 0; j < a[i].length; j++) {
    		a[i][j] = new Point(i + 1, j + 1);
    	    }
    	}
    
    	System.out.println("a =\n" + printArray(a));
    
    	Point[][] b = new Point[3][4];
    
    	for (int i = 0; i < a.length; i++) {
    	    for (int j = 0; j < a[i].length; j++) {
    		b[i][j] = new Point(a[i][j]);
    	    }
    	}
    
    	for (int i = 0; i < a.length; i++) {
    	    for (int j = 0; j < a[i].length; j++) {
    		a[i][j].setLocation(0, 0);
    	    }
    	}
    	System.out.println("a =\n" + printArray(a));
    	System.out.println("b =\n" + printArray(b));
    
        }
    
        private static String printArray(Point[][] a) {
    	StringBuilder sb = new StringBuilder();
    	for (int i = 0; i < a.length; i++) {
    	    for (int j = 0; j < a[i].length; j++) {
    		if (j > 0)
    		    sb.append("\t");
    		sb.append(a[i][j]);
    	    }
    	    sb.append("\n");
    	}
    	return sb.toString();
        }
    }
    

    which has as output:

    a =
    java.awt.Point[x=1,y=1]	java.awt.Point[x=1,y=2]	java.awt.Point[x=1,y=3]	java.awt.Point[x=1,y=4]
    java.awt.Point[x=2,y=1]	java.awt.Point[x=2,y=2]	java.awt.Point[x=2,y=3]	java.awt.Point[x=2,y=4]
    java.awt.Point[x=3,y=1]	java.awt.Point[x=3,y=2]	java.awt.Point[x=3,y=3]	java.awt.Point[x=3,y=4]
    
    a =
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]	java.awt.Point[x=0,y=0]
    
    b =
    java.awt.Point[x=1,y=1]	java.awt.Point[x=1,y=2]	java.awt.Point[x=1,y=3]	java.awt.Point[x=1,y=4]
    java.awt.Point[x=2,y=1]	java.awt.Point[x=2,y=2]	java.awt.Point[x=2,y=3]	java.awt.Point[x=2,y=4]
    java.awt.Point[x=3,y=1]	java.awt.Point[x=3,y=2]	java.awt.Point[x=3,y=3]	java.awt.Point[x=3,y=4]
    

    To get a copy of the Point object I use a constructor with the object to be copied as argument (copy constructor).
    Sometimes it is also possible to use the clone method to copy an object but be careful because the clone method might not return a copy with no connection to the original, especially if the class contains members that are not primitive because they are copied by reference.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.