Interview Kickstart has enabled over 21000 engineers to uplevel.
Whether you are a beginner or an experienced software developer, understanding arrays is crucial. Whether it’s for basic coding or implementing advanced algorithms for technical interview prep, software engineers can’t underestimate the importance of mastering arrays. In this article, we will learn all about arrays in Java. This should help coding engineers appreciate the nuanced differences in how arrays work in Java compared to languages like C or C++.
We will learn:
Let’s start with the basics.
Array definition: An array is a data structure that stores a collection of homogenous data, i.e., the elements stored in an array are all of the same data type.
All the array elements are stored under the same array name, used along with the position index to refer to individual elements within the array. Array elements are always stored contiguously, i.e., array elements are stored in order, adjacent to each other. This makes it easy to determine the locations of individual elements.
Array in Java: While the basic array definition remains the same, there are some salient features of arrays in Java. For starters, unlike some other languages like C/C++, arrays are always dynamically allocated in Java. This means that exactly the amount of memory needed can be allocated, increasing storage efficiency. We’ll discuss more such differences between arrays in Java and arrays in other languages later in the article.
String Array in Java Example: Let us now explore arrays in Java through an example of a Java array that stores 5 string type elements (department names):
String[] departmentNames = new String[5];
Array size: 5 || First Index: 0 || Last Index: 4
Note that:
Let us now discuss the ways arrays work in Java and, where appropriate, contrast it with how they work in other languages like C or C++:
Array definition is concerned with the memory allocation of the array. Memory allocation happens during array definition, which tells us where the array will get stored. Array declaration in Java is concerned with the properties of the array. It is about informing the compiler what the name of the array is, the type of data it will store, and if there’s an initial value it takes.
Different types of arrays are defined slightly differently, although the format for array declaration remains the same. There are two parts to an array declaration in Java:
Let us look at the format for declaring and defining different types of arrays:
One-dimensional array:
dataType arrayName[];
OR
dataType[] arrayName;
Two-dimensional array:
dataType arrayName[][];
OR
dataType[][] arrayName;
Multi-dimensional array (n dimensional):
dataType arrayName[][][]...n times;
OR
dataType[][][]...n times arrayName;
Different types of array variables:
//One-dimensional arrays
char charElements[];
/*charElements is an array that stores elements of type char
or char[] charElements; */
//Two-dimensional arrays
int intElements[][];
float[][] floatElements;
//Multi-dimensional arrays
short shortElements[][][];
byte[][][][] byteElements;
// array of Strings, also array of an object.
/* Strings are objects in Java that are internally backed by char arrays. */
String[] stringElements;
// an array of references to objects of a class
dessertClass dessertClassElements[];
No physical array actually exists just by declaring the array variable. To link the declared array variable with an actual physical array, we need to allocate that memory and assign it to the array variable using the keyword new. New requires us to state the data type as well as the size of the array when allocating memory using it.
The general format for memory allocation is:
//When arrayName is a 1-D array
arrayName = new dataType[size];
//When arrayName is a 2-D array
arrayName = new dataType[sizerow][sizecolumn];
//When arrayName is a n-D array
arrayName = new dataType[size1][size2]....[sizen];
?
If we already know the size of the array and values to be stored in the variables, we can use array literals. An array literal can be created using the following format:
dataType[] arrayName = new dataType[]{value1, value2,..valuesize}
The size of arrayName here will be decided by the number of values entered. The part “new dataType[]” isn’t necessary in the latest versions of Java.
Example:
//Declaring an array
char[] charElements;
//Allocating memory to the array
charElements = new char[5];
//Declaring and allocating memory in the same step
char[] charElements = new char[5];
//Array literal
char[] charElements = new char[]{‘a’,’b’,’c’,’d’,’e’};
Let us now look at the types of arrays in a bit more detail.
arrayName = new dataType[sizerow][sizecolumn];
int[][] a = new int[3][];
for(int i = 0; i < 3; i++) {
a[i] = new int[i + 1];
}
Representation:
arrayName = new dataType[size1][size2]....[sizen];
Representation:
We will also see how to implement these arrays later in the article.
We now know how to create an array. The initial values of array elements if not initialized are by default 0 for type int, 0 for type byte, 0.0 for type float, null for type string or object, and false for type boolean. We can initialize an array ourselves during its declaration itself, for example:
int[] marks = {75, 80, 99, 97, 44};
The size of the created array marks is automatically decided to be equal to the number of elements initialized, so the size is 5. Array marks now has been initialized to contain value 75 at index 0 and value 44 at index 4.
If we hadn’t initialized and just created an array of size 5, all values would have been by default set to 0. We can also, in that case, initialize values at specific positions using the index value.
Example:
//Declaration
int[] marks = new int[5];
//Initializing via index
marks[0]= 75;
marks[4]= 44;
This will lead to the following values being stored in the marks array initially:
Each array element can be accessed using the array name along with its index. Example:
System.out.println("The element at index " + 4 + " is "+ marks[4]);
We can access all elements using a single for loop.
Example:
// accessing all the elements of array marks
for (int i = 0; i < marks.length; i++)
System.out.println("The element at index " + i +" is "+ marks[i]);
We can also access all elements using a for-each loop:
for(int markValue : marks)
{
System.out.println(markValue);
}
If we try to access an element at an index greater than the largest index for the array size (size-1), the exception ArrayIndexOutOfBoundsException is thrown. This exception communicates that access to an invalid index in the array was requested. An index is illegal or invalid if it’s negative, not an integer, or is greater than or equal to array size.
Let us now implement what we have learned using an example. We will define, declare, instantiate, allocate memory to access arrays. We’ll also calculate the sum and multiplication of each array.
class Main {
public static void main(String[] args)
{
// creating arrays in a few different ways discussed
int[] oneD;
oneD = new int[5];
oneD[0] = 1;
oneD[1] = 2;
oneD[2] = 3;
oneD[3] = 4;
oneD[4] = 5;
int[][] twoD = {{0,2,4},{1,3,5}};
// accessing and printing an individual element in oneD
System.out.println("The last (fifth) element of oneD array is " + oneD[4]);
// accessing and printing all elements in oneD using for loop
System.out.println("Using for loop, elements in oneD array are ");
for(int i = 0; i < oneD.length; i++)
System.out.print(oneD[i]+" ");
// accessing and printing all elements in oneD using for each loop
System.out.println("\n Using for each loop, elements in oneD array are ");
for(int num : oneD)
System.out.print(num+" ");
// accessing and printing all elements in twoD using two for loop
System.out.println("\n Using two for loops, elements in twoD array are ");
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 3; j++)
System.out.print(twoD[i][j]+" ");
}
// accessing and printing all elements in twoD using two for-each
// loops.
System.out.println("\n Using two for-each loops, elements in twoD array are ");
for(int[] i:twoD)
{
for(int element: i)
System.out.print(element+" ");
}
// printing sum and multiplication of all elements in oneD
int oneSum = 0, oneMulti = 1;
for(int i = 0; i < oneD.length; i++)
{
oneSum+=oneD[i];
oneMulti*=oneD[i];
}
System.out.println("\n The sum of all elements in oneD array is "+oneSum+" and the product of all elements in oneD array is "+ oneMulti);
?
// printing sum and multiplication of all elements in twoD
int twoSum = 0, twoMulti = 1;
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 3; j++)
{
twoSum+=twoD[i][j];
twoMulti*=twoD[i][j];
}
}
System.out.println("The sum of all elements in twoD array is "+twoSum+" and the product of all elements in twoD array is "+ twoMulti);
}
}
The last (fifth) element of oneD array is 5
Using for loop, elements in oneD array are
1 2 3 4 5
Using for each loop, elements in oneD array are
1 2 3 4 5
Using two for loops, elements in twoD array are
0 2 4 1 3 5
Using two for-each loops, elements in twoD array are
0 2 4 1 3 5
The sum of all elements in oneD array is 15 and the product of all elements in oneD array is 120
The sum of all elements in twoD array is 15 and the product of all elements in twoD array is 0
Note: “the class Object” refers to the class java.lang.Object (the first letter O is capital) that exists in Java. On the other hand, “an object of a class” refers to an instance of any particular class that’s being considered.
class Main
{
public static void main(String args[])
{
int intElements[] = new int[5];
char charElementsA[] = new char[5];
char charElementsB[] = new char[5];
?
System.out.println("intElements is associated with " +
intElements.getClass()+ ", which is a direct subclass of "+ intElements.getClass().getSuperclass());
System.out.println("charElementsA is associated with "+ charElementsA.getClass()+", which is a direct subclass of "+ charElementsA.getClass().getSuperclass());
System.out.println("charElementsB is associated with "+ charElementsB.getClass()+", which is a direct subclass of "+ charElementsB.getClass().getSuperclass());
}
}
intElements is associated with class [I, which is a direct subclass of class java.lang.Object
charElementsA is associated with class [C, which is a direct subclass of class java.lang.Object
charElementsB is associated with class [C, which is a direct subclass of class java.lang.Object
Arrays are objects of a class, and the class “Object” acts as its direct superclass. The members associated with an array include an instance method called length, which tells us the size of the array. It also includes the members the class Arrays inherits from its direct superclass Object.
Arrays inherit all methods of the Object class except the clone() method. A public method clone() overrides the original clone() method present in the class Object.
Like we do with variables, arrays can be both passed as a parameter to a method and returned from it as the result.
class Main
{
// Passing an array as a parameter to the method findOdd
public static int[] findOdd(int[] array)
{
// Getting sum of array values
// Given small original array size, for simplicity, we
// can have oddArray be the same size as the original
// array. For bigger arrays we can count odd elements
// using a for loop to determine the exact size needed.
int[] oddArray = new int[array.length];
int tracker =0;
for (int i : array)
{
if (i%2==1) {oddArray[tracker]=i; tracker++;}
}
//Returning an array from the method findOdd
return oddArray;
}
public static void main(String args[])
{
int array[] = {7, 1, 8, 6, 3};
int[] oddArray= findOdd(array);
System.out.println("Odd elements in the array are ");
for (int i : oddArray)
if(i!=0) System.out.print(i+ " ");
}
}
The output of the above code is
Odd elements in the array are
7 1 3
An array can be copied from one array to some other array by importing java.util.Arrays and using the Arrays.copyOf() method in it. This will work by storing elements of the original array into the copied array.
Cloning a 1-D array leads to a deep copy, but cloning a multi-dimensional array leads to a shallow copy. Deep copy involves using copies of the original array’s elements instead of references. Shallow copy involves using references to the original array’s elements. In a deep copy, any change made to the copy will not be reflected in the original array. In a shallow copy, the change to the copy will be reflected in the original array. We can perform cloning in java using the clone() method.
Let us see how the two can be implemented in Java.
import java.util.Arrays;
class Main {
public static void main(String[] args)
{
// Creating and printing the original array
int[] originalArray={1,2,3,4,5};
System.out.println("The original array to duplicate ");
for(int num: originalArray)
System.out.print(num+" ");
// Creating a copy of the array
System.out.println("\n The copy of the array is ");
int[] copiedArray = Arrays.copyOf(originalArray, originalArray.length);
for(int numCopy: copiedArray)
System.out.print(numCopy+" ");
// Creating a clone of the array
System.out.println("\n The clone of the array is ");
int clonedArray[]= originalArray.clone();
for(int numClone: clonedArray)
System.out.print(numClone+" ");
//Showing shallow copy through 2-D arrays
int[][] twoD = {{0,2,4},{1,3,5}};
System.out.println("\n The 2-D array is ");
for(int[] i: twoD)
for(int num: i)
System.out.print(num+" ");
// Creating a clone of the 2-D array
System.out.println("\n The clone of the 2-D array is ");
int clonedtwoD[][]= twoD.clone();
for(int[] i: clonedtwoD)
for(int numClone: i)
System.out.print(numClone+" ");
// Changing clonetwoD changes the original as it's a shallow copy
clonedtwoD[0][0]=100;
clonedtwoD[0][1]=100;
clonedtwoD[0][2]=100;
System.out.println("\n The clone of the 2-D array now is ");
for(int[] i: clonedtwoD)
for(int numClone: i)
System.out.print(numClone+" ");
System.out.println("\n The 2-D array now is ");
for(int[] i: twoD)
for(int num: i)
System.out.print(num+" ");
}
}
The output of the above code is:
The original array to duplicate
1 2 3 4 5
The copy of the array is
1 2 3 4 5
?
The clone of the array is
1 2 3 4 5
The 2-D array is
0 2 4 1 3 5
The clone of the 2-D array is
0 2 4 1 3 5
The clone of the 2-D array now is
100 100 100 1 3 5
The 2-D array now is
100 100 100 1 3 5
Advantages:
Disadvantages:
Visit our interview questions and problems page to learn more.
Question 1: What is the difference between dataType[] arrayName; vs dataType arrayName[]; for declaration? Which one should one prefer in what situations?
Answer: While essentially the same, it can be useful to use one over the other in certain cases. For example, if many variables along with an array of the same data type are to be declared, we can write it better as dataType arrayName[], variableA, variableB. On the other hand, if many arrays of the same data type have to be declared, we can write it better as dataType[] arrayNameA, arrayNameB; in a single line.
Question 2: What is a jagged array?
Answer: A multidimensional array in which its member arrays are not of the same size is known as a jagged array. An example would be creating a 2-D array with a variable number of columns. Int[][] array = new int[3][] can be a jagged array by having member arrays array[0][3], array[1][2] and array[2][4].
If you’re looking for guidance and help to nail these questions and more, sign up for our free webinar. As pioneers in the field of technical interview prep, we have trained thousands of software engineers to crack the toughest coding interviews and land jobs at their dream companies, such as Google, Facebook, Apple, Netflix, Amazon, and more!
------------
Article contributed by Tanya Shrivastava
Attend our webinar on
"How to nail your next tech interview" and learn