Arrays - Introduction

Brief introduction of Arrays as a Data Structure.

Arrays - Introduction

Table of Contents

Array Definition
Static Arrays
       Declaring and Initializing an array
       Accessing and Updating an array
Dynamic Arrays
       Declaring and Initializing a Dynamic Array
       CRUD operations on a Dynamic Array
Best Practices related to Arrays
       When to use Arrays
       When not to use Arrays


Arrays are one of the most commonly used data structure in the programming world.


Array Definition

Array is a collection of data elements, stored next to each other.
An Array is used to refer to a set of values such as Integers, Animal names, etc. via a single variable.


For the sake of brevity, we will be using Java for writing code and providing examples in this and all the upcoming series. However, keep in mind that the concepts and solutions provided are universal and transcends any language limitations.


Arrays can broadly be defined in terms of size and dimension:

Size:
Static Arrays (Fixed Size)
Dynamic Arrays (Variable Size)

Dimension:
Single Dimension (Single row of elements)
Multi-Dimension (Multiple row of elements, such as a table)

Below we will dicuss these various types of Arrays along with Array operations such as Read, Delete, etc.


Static Arrays

These arrays have a fixed-size that is pre-defined at the time of initialization.

Declaring and Initializing an array

We can declare an array by giving it a name and defining the data type of its elements.

Declaring an Array
int[] anArray;

However, declaring won't actually create the array. It just tells the compiler that there is an array with the given name.
To create an array in memory, we need to initialize the array using the new keyword.

Initializing Array with new keyword
anArray = new int[5];
// Initializes all elements with a default vaue of 0

Or we can initialize elements with their specific values

Initializing Array with specific values
anArray = [1, 2, 3, 4, 5];

Declaring, Allocating memory and Initializing an array:

// In two lines
int[] anArray = new int[5];
anArray = [1, 2, 3, 4, 5];

// In one line using an Array Literal
int[] anArray = new int{1, 2, 3, 4, 5};

Accessing and Updating an array

In computing world, we start counting from 0, instead of 1. So, Array indexes also start from 0.

We can access an array element using it's index:

Accessing an array
return anArray[0];
// returns 1

We can also update an array element using it's index:

Updating an array element
anArray[0] = 11;
// updates value from 1 -> 11

Array Length anArray.length; // Returns Length of the array

Iterating over arrays
We can also access or update each element by iterating over the whole array, using loops:

  • For Loop (Most Common)
for (int i=0; i < arr.length; i++) {  
  System.out.println(arr[i]);  
}

// Better way
for (int elem : arr) {
  System.out.println(elem);
}

// Both the loops print an element present at index i
  • While Loop
    When we want to iterate over the array, until a condition is met, like index < 10
int i = 0;
while (i < 10) {
  System.out.println(arr[i]);
  i++;
}
// Prints array elements till Index 9 (Inclusive)

Arrays are immutable, which means that we cannot add or delete array elements after initialization.
Adding or deleting elements, requires us to create a new Array.

Static Arrays in one block

// Declaring and Initializing Arrays
int a[] = new int[5];

int b[] = new int[5];
b = [1, 2, 3, 4, 5];

int c[] = new int{6, 7, 8, 9, 10};

// Updating Arrays
c[0] = 11; 
c[1] = 22; 

// Iterating over the Arrays
// For Loop
for (int i=0; i<a.length; i++) {
  System.out.println(a[i]);
}
// prints 0 five times in separate rows

// For Loop (Better way)
for (int elem : b) {
  System.out.println(elem);
}
// prints 1, 2, 3, 4, 5 respectively in separate rows

// While Loop
int j = 0;
while (j<5) {
  System.out.println(c[j]);
  j++;
}
// prints 11, 22, 6, 7, 8 respectively in separate rows

Dynamic Arrays

Dynamic Arrays are very commonly used as a replacement for normal Arrays.

Dynamic Arrays help us in:

  1. Creating unknown size Arrays
  2. Adding and removing elements without creating a new array

The data structure used in Java for Dynamic Arrays is ArrayList.

Declaring and Initializing a Dynamic Array (ArrayList)

Empty ArrayList
ArrayList<Integer> nums = new ArrayList<Integer>();

We can also initialize an ArrayList with values using an array as a List.

ArrayList with values
ArrayList<Integer> nums = new ArrayList<Integer>(Arrays.asList(1, 2, 4));

ArrayList Length nums.size(); // Returns length or size of the ArrayList

Note: We use wrapper classes instead of primitve data types (such as int) while creating an ArrayList.

CRUD operations on a Dynamic Array (ArrayList)

CRUD stands for Create Read Update Delete

Below we will learn the methods used to perform CRUD operations on an ArrayList:

Create

  1. Adding an element to the end of the ArrayList
    Function
    add(v) where v = value of the element

    Example
    nums.add(3);
    // Adds an element with value 3 to the end of the ArrayList

  2. Adding an element at a specific index in the ArrayList
    Function
    add(i, v)
    where i = index where element should be inserted
    and v = value of the element

    Example
    nums.add(5, 8);
    // Inserts an element with value 8 at the 6th position
    // (since indexing starts from 0) in the ArrayList

Read

  1. Accessing an element in the ArrayList
    Function
    get(i) where i = index of the element

    Example
    nums.get(2);
    // Returns an element at position 3 in the ArrayList

Update

  1. Updating an element based on index
    Function
    set(i, v)
    where i = index of the element
    and v = value of the element

    Example
    nums.set(2, 10);
    // Updates element at position 3 to value 10 in the ArrayList

Delete

  1. Deleting an element based on index
    Function
    remove(i) where i = index of the element

    Example
    nums.remove(2);
    // Deletes element at position 3 in the ArrayList

  2. Deleting an element based on element value
    Function
    remove(v) where v = value of the element

    Example
    nums.remove(new Integer(10));
    // Deletes an integer with value 10 from the ArrayList

Dynamic Arrays in one block

// -------- Example 1  --------------
// Declaring and Initializing ArrayLists
ArrayList<Integer> a = new ArrayList<Integer>();

// Adding elements to arraylist
a.add(6);
a.add(7);

// Reading elements of an arraylist
for (int i=0; i<a.size(); i++) {
  System.out.println(a.get(i));
}
// Prints 6, 7 in separate rows

// Updating elements of an arraylist
a.set(0, 66);
// Updates value at index 0 to 66

// Deleting elements of an arraylist
a.remove(1);
// Removes value at index 1

// Iterating one more time
int i = 0;
while (i < a.size() ) {
  System.out.println(a.get(i));
}
// Prints 66 as the only element left int the arrayList

// -------- Example 2  --------------
ArrayList<Integer> b = new ArrayList<Integer>(Arrays.asList(1, 2, 3));

// Adding elements to arraylist
b.add(4);

// Adding elements to arraylist at a specific index
b.add(1, 11);

// Reading elements of an arraylist
for (int i=0; i<b.size(); i++) {
  System.out.println(b.get(i));
}
// Prints 1, 11, 2, 3, 4 in separate rows

// Updating elements of an arraylist
b.set(1, 111);
// Updates value at index 1 to 111

// Deleting elements of an arraylist
b.remove(new Integer(4));
// Removes Integer 4 from the arrayList

// Iterating one more time
int j = 0;
while (j < b.size()) {
  System.out.println(b.get(i));
}
// Prints 1, 111, 2, 3 in separate rows

Best practices related to Arrays

Use the right tool for the rigth job

When to use Arrays

Arrays are generally useful when we need to perform quick read/write operations as they provide access to it's elements in constant O(1) time.

Array elements are stored in individual adjacent memory blocks, otherwise known as contiguous memory. If we are given an array arr with n elements, we can access its elementarr[i] directly by referencing the (arr[0] + i)th block in memory.

Example :
System.out.println(arr[100]);

Above statement will run in O(1) time, because the computer knowns that the value at index 100 is stored 100 memory blocks ahead of the 0th index, making it readily available. This will also save us the time which could have been wasted otherwise in traversing 100 elements taking O(n) time.

The time taken to access an array item stored at 1st index or 10,000th index would be same.

When not to use Arrays

In order to achieve constant read/write access, we need to make sacrifice on another aspect i.e. Memory
Arrays store elements in contiguos memory location, Therefore, we need to define the size of the array before initialization, which means we have to allocate space to an array before even knowing how much we might need it.

What happens when we don't know how much would be the size of the array :

  1. We might create a too big array:
    This will waste precious memory space which can be used to store data or run other programs.
  2. We might create a too small array:
    This will prevent us from saving all of our data and lead to Data Loss.

We can overcome the above limitations by using a Dynamic Array.


👋 Say "Hi" on Whatsapp
🤝 Connect on Linkedin
🙏 ...Thanks for reading