Thursday, November 14, 2013

10 Points about Array type in Java

Array is one of the most important data structure in any programming language, at same time different programming languages implement and treat array differently. Any one who is done some programming knows value of array and importance of knowing about array type, using them in there program. Together with linked list, array forms a set of basic data-structures. Though Java offers excellent Collection API and some of collection classes like ArrayList and  HashMap , they are internally based on array.  If you are coming from C or C++ background then you will find some difference about how array behaves there and how it does in Java, most notable difference between array in C and array in Java is bounds checking. C compiler doesn't check if program is accessing valid array index, while in Java, JVM does that and throws ArrayIndexOutOfBoundException, if program tries to access invalid array index. In this Java article, we will take a look on array in Java, both primitive and object arrays. It's a collection of important things about Java array and there properties.


Java Array 101

1) Array in Java is object and array instance is also created using new operator. Array.length gives length of array.
for example for following java array:

int[] intArray = new int[10];
System.out.println(intArray.length)

Output: 10

Array.length denotes it’s capacity, because each index is initialized with default value, as soon as array is created.

2) Array index in Java starts with zero. Negative indexes are invalid in Java. Java will throw ArrayIndexOutOfBoundException ,if you try to access an Array with invalid index which could mean
negative index, index greater than or equal to length of array in Java.

3) Array are fixed length data structure. Once declared, you can not change length of Array in Java.

4) Array are stored at contiguous memory location in Java Heap. So if you are creating a large array it is possible that you might have enough space in heap but still Java throw OutOfmemoryError because of requested sized might not be available on contiguous memory location.

5) Different type of Array in Java have different types representing them for example in below example intArray.getClass() will be different than floatArray.getclass()

int[] intArray = new int[10];
float[] floatArray = new float[10];


6) You can not store a double value in an array of int, that would result in compilation error.

int[] intArray = new int[10];
intArray[5]=1.2; //compilation error

if you try to do this operation in runtime, Java will throw ArrayStoreException

7) In Java Array can be created by different ways. here are few examples of creating array in Java

int[] intArray;   //creating array without initializing or specifying size
int intArray1[];  //another int[] reference variable can hold reference of an integer array
int[] intArray2 = new int[10]; //creating array by specifying size
int[] intArray3 = new int[]{1,2,3,4}; //creating and initializing array in same line.

you have choice to initialize java array while creating it alternatively you can initialize array later by using for loop. If you have noticed brackets which is used to denote array can be placed either side of array variable.

First approach is convenient for creating multiple arrays in Java e.g.

int[] array1, array2;

here both array1 and array2 are integer array, while in second approach you need to place bracket twice like

int array1[], array2[];

though not much difference it just matter of style, I read int[] as int array so first approach fits perfect there.

8) If not initialized explicitly array elements in are initialized with default value of Type used to declare Java array. For example in case of an uninitialized integer array there element will have default value 0, for uninitialized boolean array it would false and for an Object array it would be null.


9) You can access element of Array by using [] operator. Since array index starts at zero [0] returns first element and [length-1] returns last element from array in Java. For loop is a convenient way to iterate over entire array in Java. You can use for loop to initialize entire array be accessing each index or you can update/retrieve array elements. Java 5 also provides enhanced for loop which will take care of array indexes by themselves and prevent ArrayIndexOutOfBoundException in Java. Here is an example of iterating array in Java using for loop.

Traditional approach

int[] numbers = new int[]{10, 20, 30, 40, 50};

for (int i = 0; i < numbers.length; i++) {
  System.out.println("element at index " + i + ": " + numbers[i]);
}

Output:
element at index 0: 10
element at index 1: 20
element at index 2: 30
element at index 3: 40
element at index 4: 50

Enhanced for loop approach

for(int i: numbers){
   System.out.println(i);
}

Output:
10
20
30
40
50

As you see in case case enhanced for loop we don't need to check for indexes and its an excellent way if you want to access all element of array one by one but at the same time since you don't have access to index you can modify any element of Java array.

10) In Java you can easily convert an array into ArrayList. ArrayList is index based Java collection class which is backed up array. advantage of ArrayList is that it can resize itself. resizing of ArrayList is just creating a larger array and copying content to that array as you can not change size of array in Java. check how to convert Array to ArrayList in Java for more details.

11) Java API Also provide several convenient method to operate on Java array via java.util.Arrays class. By using Arrays class you can sort an array in Java and you can also perform binary search in Java.

12) java.lang.System class provides utility method for copying elements of one array into another. System.arrayCopy is very powerful and flexible method of copying contents from one array to another. You can copy entire array or sub-array based on your need.

Syntax of System.arraycopy:

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

As you see arraycopy() method allow us to specify indexes and length which gives your flexibility to copy sub-array
and store it on desired location of destination or target array. here is an example of copying first three elements of source array into target array in Java:

public static void main(String args[]) {
        int[] source = new int[]{10, 20, 30, 40, 50};
        int[] target = new int[5];
      
        System.out.println("Before copying");
        for(int i: target){
            System.out.println(i);
        }
      
        System.arraycopy(source, 0, target, 0, 3);
      
        System.out.println("after copying");
        for(int i: target){
            System.out.println(i);
        }
    }
Output:
Before copying
0
0
0
0
0
after copying
10
20
30
0
0

You can see before copying all elements of target array were zero(default value of int variable) and after copying first 3 elements represent first 3 items of source array.

13) Java also supports multi-dimensional arrays, which can be very useful to represent 2D and 3D based data like rows and columns or matrix. multi-dimensional array in Java are also referred as array of array because in each index of first array another array is stored of specified length. here is an example of creating multi-dimensional array in Java:

int[][] multiArray = new int[2][3];

This array has two rows and 3 column or you can visualize it as array of 3 arrays with length 2. Here is how you can initialize multi-dimensional array in Java:

int[][] multiArray = {{1,2,3},{10,20,30}};
System.out.println(multiArray[0].length);
System.out.println(multiArray[1].length);

Alternatively you can also initialize multi-dimensional array individually by using for loop or manually. e.g.
multiArray[0] = new int[]{40,50,60};  will replace value of multiArray[0].

14)  Array is extremely fast data-structure and one should use it if you already know number of elements going to be stored.

That's all about Array in Java. As you see Java array are very powerful way of storing elements and provides fastest access if you know the index. Though it also has limitation e.g. once created you can not change the size of array, but if you ever need a dynamic array, consider using java.util.ArrayList class. It provides dynamic re-size functionality and auto re-size itself. Its also very easy to convert an Array into ArrayList and operate on that.

2 comments :

Anonymous said...

Hello there? I have some questions on Java arrays :

1) Some people declare array as int[] numbers and some as int numbers[] , what is the difference between these two approaches?

2) Why Java index starts at 0, instead of 1? any specific reason, other than a random pick
3) Why negative index for arrays is not allowed in Java?

SARAL SAXENA said...

@Javin perfect article on arrays , really nice article just want to add with context to OutOfmemoryError...
he detail message Requested array size exceeds VM limit indicates that the application (or APIs used by that application) attempted to allocate an array that is larger than the heap size. For example, if an application attempts to allocate an array of 512MB but the maximum heap size is 256MB then OutOfMemoryError will be thrown with the reason Requested array size exceeds VM limit. In most cases the problem is either a configuration issue (heap size too small), or a bug that results in an application attempting to create a huge array, for example, when the number of elements in the array are computed using an algorithm that computes an incorrect size.

I wrote a sample program:

public class VmLimitTest {

public static final int SIZE = 2;

public static void main(String[] args) throws InterruptedException {
while(true) {
byte[] a = new byte[SIZE * 1024 * 1024];
TimeUnit.MILLISECONDS.sleep(10);
}
}
}

And run it with the following JVM options:

-Xms192m -Xmx192m -XX:NewRatio=2 -XX:SurvivorRatio=6 -XX:+PrintGCDetails

This is what they mean:

The whole heap is 192 MiB (-Xms192m -Xmx192m)
The young generation (eden + survivor) space is 64 MiB, old generation is 128 MiB (-XX:NewRatio=2)
Each survivor space (out of two) is 8 MiB, so 48 MiB is left for eden (1:6 ratio, -XX:SurvivorRatio=6)

While testing I discovered the following:

If the newly created array can fit into eden (less than 48 MiB), the program runs fine
Surprisingly, when the array size exceeds eden size, but can fit into eden and one survivor space (between 48 and 56 MiB), JVM can allocate a single object on both eden and survivor (overlapping two areas). Neat!
Once the array size exceeds eden + single survivor (above 56 MiB) the newly created object is placed directly in old generation, bypassing eden and survivor spaces. This also means that suddenly full GC is performed all the time - very bad!
I can easily allocate 127 MiB of data but trying to allocate 129 MiB will throw OutOfMemoryError: Java heap space

This is the bottom line - you cannot create an object with size larger than old generation. Trying to do so will result in OutOfMemoryError: Java heap space error. So when can we expect dreadful Requested array size exceeds VM limit?

I tried running the same program with much larger objects. Hitting the array length limit I switched to long[] and could easily go up to 7 GiB. With 128 MiB of max heap declared the JVM was still throwing OutOfMemoryError: Java heap space (!) I managed to trigger OutOfMemoryError: Requested array size exceeds VM limit error trying to allocate 8 GiB in a single object. I tested this on a 32-bit Linux computer with 3 GiB of physical memory and 1 GiB of swap.

That being said you should probably never hit this error. The documentation seems inaccurate/outdated, but it is true in one conclusion: this is probably a bug since creating such huge arrays is very uncommon.

Post a Comment