Performing a fast array copy

The System class contains a method called arraycopy that copies an array or part of an array to another one. You specify a source array (the elements that are being copied) and a destination array (where the elements should go). You should have allocated enough memory for the destination array to hold the new values. Also, you can specify the source offset that indicates from what index the copying should start and an destination offset that indicates what index the values should be copied to. The types of the source array and destination array should match (eg. you can’t copy elements from an object array into an integer array) or an ArrayStoreException will be thrown.

This example copies 5 elements from arr starting from index 3 into arr2 starting from index 0.

Main.java:

import java.util.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      int arr[] = { 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9 };
      int arr2[] = new int[5];
      System.arraycopy(arr, 3, arr2, 0, 5);
 
      System.out.print("arr:nt");
      printArray(arr);
      System.out.print("arr2:nt");
      printArray(arr2);
   }      
 
   public static void printArray(int []arr) {
      for (int i=0; i<arr.length; i++) {
         System.out.print(arr[i] + " ");
      }
      System.out.println();
   }
}

Increasing the size of an array

You can’t. You will have to create a new bigger array and copy the original one into it. A fast array copy can be achieved with System.arraycopy.

In the following example, we create an integer array of size 10 and increase it to 20.

Main.java:

public class Main {
   public static void main(String args[]) {
      int intArray[] = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 
      System.out.print("Before: ");
      printArray(intArray);
  
      intArray = enlargeIntArray(intArray, 20);
 
      System.out.print("After:  ");
      printArray(intArray);
   }
 
   public static int[] enlargeIntArray(int []intArray, int size) {
      // include code here to throw exception when intArray.length > size
 
      int newIntArray[] = new int[size];
      System.arraycopy(intArray, 0, newIntArray, 0, intArray.length);
      return newIntArray;            
   }
 
   public static void printArray(int []intArray) {
      for (int i=0; i<intArray.length; i++) {
         System.out.print(intArray[i] + " ");
      }
      System.out.println();
   }
}

outputs:

Before: 1 2 3 4 5 6 7 8 9 10 
After:  1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0

The problem with this code is that it is not very flexible. What if you want to increase the size of a String array? You would have to create a new similar method for that purpose. Java doesn’t include a Templates architecture, the first thing that would come to mind to solve this problem when programming in C++. However, you can use something fancy called reflection. The whole program evolves around the standard API class Array in which you can “dynamically” create and modify arrays, given the class type and the size.

Following example shows how to increase the size of an integer array and a float array with the same method.

Main.java:

import java.lang.reflect.*;
 
public class Main {
   public static void main(String args[]) {
      int intArray[] = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
 
      System.out.print("Before: ");
      printArray(intArray);
      intArray = (int[]) enlargeArray(intArray, 20);
      System.out.print("After:  ");
      printArray(intArray);
 
      double doubleArray[] = new double[] { 0.9, 1.8, 2.7, 3.6, 4.5, 
                                            5.4, 6.3, 7.2, 8.1, 9.0 };
 
      System.out.print("Before: ");
      printArray(doubleArray);
      doubleArray = (double[]) enlargeArray(doubleArray, 20);
      System.out.print("After:  ");
      printArray(doubleArray);
   }
 
   public static Object enlargeArray(Object oldArray, int size) {
      // include code here to throw exception when oldArray.length > size
 
      Object newArray = Array.newInstance(oldArray.getClass().getComponentType(), size);
      System.arraycopy(oldArray, 0, newArray, 0, Array.getLength(oldArray));
      return newArray;
   }
 
   public static void printArray(Object array) {
      for (int i=0; i<Array.getLength(array); i++) {
         System.out.print(Array.get(array, i) + " ");
      }
      System.out.println();
   }
}

outputs:

Before: 1 2 3 4 5 6 7 8 9 10 
After:  1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0 
Before: 0.9 1.8 2.7 3.6 4.5 5.4 6.3 7.2 8.1 9.0 
After:  0.9 1.8 2.7 3.6 4.5 5.4 6.3 7.2 8.1 9.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 

Randomly shuffling an array

Take two random numbers between 0 and the length of the array (bounds inclusive) and swap the values.

This example shows you a method that can take an array of any type and just swaps references around.

Main.java:

import java.util.*;
import java.io.*;
import java.lang.reflect.*;
 
public class Main
{
   public static void main(String []args) {
      int[] arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  
      System.out.print("Before:nt");
      printArray(arr);
 
      shuffleArray(arr); 
 
      System.out.print("After:nt");
      printArray(arr);
   }
  
   public static void printArray(int []arr) { 
      for (int i=0; i<arr.length; i++) {
         System.out.print(arr[i] + " ");
      }
      System.out.println();
   }
 
   public static void shuffleArray(Object arr) {
      Random r = new Random();
      for (int i=0; i<100; i++) {
         int r1 = Math.abs(r.nextInt() % 10);
         int r2 = Math.abs(r.nextInt() % 10);
         Object el0 = Array.get(arr, r1);
         Object el1 = Array.get(arr, r2);
         Array.set(arr, r2, el0);
         Array.set(arr, r1, el1);
      }
   }
}

outputs:

Before:
	0 1 2 3 4 5 6 7 8 9 
After:
	1 4 7 3 5 9 6 2 8 0 

Find the maximum value of an array

Just set a variable max to the minimum value possible that your type can contain, for example max = Integer.MIN_VALUE; for an integer array and then loop through all the array’s elements reassigning max every time a higher value is found.

Main.java:

import java.util.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      int arr[] = { 10, 8, 6, 4, 2, 11, 3, 5, 7, 9 };
 
      System.out.println("Maximum: " + findMax(arr));
   }
 
   public static int findMax(int[] arr) {
      int max = Integer.MIN_VALUE;
      for (int i=0; i<arr.length; i++) {
         if (arr[i] > max) {
            max = arr[i];
         }
      }
      return max;
   }
}

Finding the minimum value of an array

Just set a variable min to the maximum value possible that your type can contain, for example min = Integer.MAX_VALUE; for an integer array and then loop through all the array’s elements reassigning min every time a lower value is found.

Main.java:

import java.util.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      int arr[] = { 10, 8, 6, 4, 2, 1, 3, 5, 7, 9 };
 
      System.out.println("Minimum: " + findMin(arr));
   }
 
   public static int findMin(int[] arr) {
      int min = Integer.MAX_VALUE;
      for (int i=0; i<arr.length; i++) {
         if (arr[i] < min) {
            min = arr[i];
         }
      }
      return min;
   }
}

Comparing two arrays

If you want to compare if two arrays point to the same memory, you can simply compare its references:

import java.util.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      int arr[] = { 10, 8, 6, 4, 2, 11, 3, 5, 7, 9 };
 
      int arr2[] = arr;
 
      if (arr == arr2) {
         System.out.println("Arrays are equal"); 
      } 
      else {
         System.out.println("Arrays are not equal"); 
      }
   }
}

If you want to compare each and one of the values of the array’s elements are equal, you can use the handy method equals in the Arrays class. Here’s an example:

import java.util.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      int arr[] = { 10, 8, 6, 4, 2, 11, 3, 5, 7, 9 }; 
      int arr2[] = { 10, 3, 6, 4, 2, 11, 3, 5, 7, 9 };
 
      if (Arrays.equals(arr, arr2)) {
         System.out.println("Arrays are equal");
      }
      else {
         System.out.println("Arrays are not equal");
      }
   }
}

Filling up an array

Since JDK1.2, the utility class Arrays in the java.util package provides useful
array manipulation methods such as fill, binary search and sort.

You can easily fill up an array with a for loop:

      int values[] = { 5, 74, 23, 99, 6, 0, -2, -60 };
 
      for (int i=0; i<values.length; i++)
         values[i] = 69;

You could also use the Arrays.fill method defined for arrays of type byte[], char[],
double[], float[], int[], long[], object[].

Eg.

      Arrays.fill(values, 69);

It doesn’t work any faster than writing the for loop yourself, it does exactly
the same (contains a for loop), except that it does some range checking.
So, theoretically using Arrays.fill is slower, but your code looks a lot cleaner.
Range checking is necessary if you want to fill up only part of the array using
fill(array, fromvalue, tovalue, value).

      Arrays.fill(values, 1, 4, 69);  yields in the array { 5, 69, 69, 69, 6, 0, -2, -60 }

Binary searching an array

Since JDK1.2, the utility class Arrays in the java.util package provides useful
array manipulation methods such as fill, binary search and sort. Before using
the binary search method, you should make sure the array is sorted. Binary searching
on an unsorted array gives undefined results. The binarySearch function is defined
for arrays of type byte[], char[], double[], float[], int[], long[], object[].

You pass the method the key you want to lookup. It returns with either
the index, if the key is found, or the insertion point defined as
(-return value)-1, as the index where the value should be inserted to keep
the array sorted.
Following example demonstrates the use:

import java.util.Arrays;
 
public class Main
{
   public static void main(String args[]) {
      int values[] = { 5, 74, 23, 99, 6, 0, -2, -60 };
 
      System.out.println("Unsorted array:");
      printArray(values);
 
      Arrays.sort(values);
 
      System.out.println("Sorted array:");
      printArray(values);
 
      int v1 = 6;
      int v2 = 34;
      int r1 = Arrays.binarySearch(values, v1);
      int r2 = Arrays.binarySearch(values, v2);
 
      printResult(v1, r1);
      printResult(v2, r2);
   }
 
   public static void printArray(int []values) {
      for (int i=0; i<values.length; i++) {
         System.out.print(values[i] + " ");
      }
      System.out.println();
      System.out.println();
   }
 
   public static void printResult(int value, int index) {
      if (index < 0) {
         int ip = -index - 1;
         System.out.println(value + " not found.  Insertion point = " + ip);
      }
      else {
         System.out.println(value + " found at index " + index);
      }
   }
}

outputs:

Unsorted array:
5 74 23 99 6 0 -2 -60 
 
Sorted array:
-60 -2 0 5 6 23 74 99 
 
6 found at index 4
34 not found.  Insertion point = 6

You can just as easily binary search on user-defined objects. The only catch
is that you will have to define a comparator to tell the method whether object
A is less than, equal or bigger than object B.
Here’s an example:
RedColorComparator is introduced, a Comparator that only takes into account the red value of
the RGB value.

import java.util.Comparator;
import java.util.Arrays;
import java.awt.Color;
 
public class Main
{
   public static void main(String []args) {
      Color colArr[] = { new Color(43, 100, 100), new Color(170, 59, 255),
                            new Color(0, 0, 0), new Color(220, 220, 220),
                            new Color(10, 255, 255), new Color(255, 0, 0) };
 
      System.out.println("Unsorted array:");
      printArray(colArr);
      Arrays.sort(colArr, new RedColorComparator());
      System.out.println("Sorted array:");
      printArray(colArr);
 
      Color v1 = new Color(220, 220, 220);
      Color v2 = new Color(11, 0, 0);
      int r1 = Arrays.binarySearch(colArr, v1, new RedColorComparator());
      int r2 = Arrays.binarySearch(colArr, v2, new RedColorComparator());
  
      printResult(v1, r1);
      printResult(v2, r2);
   }
 
   public static void printArray(Color colArr[]) {
      for (int i=0; i<colArr.length; i++) 
         System.out.println(colArr[i]);
      System.out.println();
   }
 
   public static void printResult(Color value, int index) {
      if (index < 0) {
         int ip = -index - 1;
         System.out.println(value + " not found.  Insertion point = " + ip);
      }
      else {
         System.out.println(value + " found at index " + index);
      }
   }
}
 
class RedColorComparator implements Comparator
{
   public int compare(Object o1, Object o2) {
      int red1 = ((Color) o1).getRed();
      int red2 = ((Color) o2).getRed();
      return (new Integer(red1)).compareTo(new Integer(red2));
   } 
}

outputs:

Unsorted array:
java.awt.Color[r=43,g=100,b=100]
java.awt.Color[r=170,g=59,b=255]
java.awt.Color[r=0,g=0,b=0]
java.awt.Color[r=220,g=220,b=220]
java.awt.Color[r=10,g=255,b=255]
java.awt.Color[r=255,g=0,b=0]
 
Sorted array:
java.awt.Color[r=0,g=0,b=0]
java.awt.Color[r=10,g=255,b=255]
java.awt.Color[r=43,g=100,b=100]
java.awt.Color[r=170,g=59,b=255]
java.awt.Color[r=220,g=220,b=220]
java.awt.Color[r=255,g=0,b=0]
 
java.awt.Color[r=220,g=220,b=220] found at index 4
java.awt.Color[r=11,g=0,b=0] not found.  Insertion point = 2