Introduction to Java Programming.

Chapter 1: Introduction to Java Programming

1.11 Organizing Data: Arrays in Java

Arrays are powerful and commonly used data structures in Java. They provide a way to store a fixed-size sequential collection of elements of the same data type. Think of an array as a list or a container that can hold multiple values under a single name.

1.11.1 Introduction to Arrays: Why Use Them?

      Need for Storing Multiple Values of the Same Type |:


Imagine you need to store the scores of 100 students, or the temperatures for each day of a month. Without arrays, you would have to declare 100 separate int variables for scores (score1, score2, …, score100), which is cumbersome and inefficient. Arrays solve this problem by allowing you to declare a single variable that can hold all these values.

      Contiguous Memory Allocation |:


Conceptually, elements in an array are stored in contiguous (adjacent) memory locations. This allows for very fast access to elements using an index. While the JVM handles the actual memory allocation, the idea is that elements are "next to each other" in a logical sense.

      Zero-based Indexing |:
In Java (and most other programming languages), array elements are accessed using an index. Arrays are zero-indexed, meaning the first element is at index 0, the second at index 1, and so on. If an array has N elements, the last element is at index N-1.

1.11.2 One-Dimensional (1D) Arrays

A one-dimensional array is like a single row or column of values.

      Declaration |:


Declaring an array tells the compiler the type of elements the array will hold. You can use two forms for declaration, though dataType[] arrayName; is generally preferred for readability as it clearly indicates that arrayName is an array.

      Syntax 1: dataType[] arrayName;

      Syntax 2: dataType arrayName[];

            Examples:

int[] numbers;        // Preferred way to declare an integer array String names[];       // Valid, but less common way to declare a String array boolean[] flags;      // Declares a boolean array

      Instantiation |:


Instantiation (or creation) means allocating memory for the array. When you instantiate an array, you must specify its size (how many elements it can hold). All elements are automatically initialized to their default values (e.g., 0 for int, null for String, false for boolean) when instantiated.

      Syntax: arrayName = new dataType[size];

            Examples:

 // Instantiating an integer array of size 5

int[] numbers = new int[5];        // Indices: 0 to 4

 

// Instantiating a String array of size 10

String[] names = new String[10];   // Indices: 0 to 9

 

// Instantiating a boolean array of size 3

boolean[] flags = new boolean[3];  // Indices: 0 to 2

      Initialization |:
Initialization means assigning actual values to the individual elements of the array. You access each element using its index.

      Syntax: arrayName[index] = value;

            Examples:

 // Integer array

int[] numbers = new int[5]; // Instantiate an array of 5 integers

numbers[0] = 10;            // Assigns 10 to the first element

numbers[1] = 20;            // Assigns 20 to the second element

numbers[2] = 30;            // Assigns 30 to the third element

 

// String array

String[] names = new String[3];

names[0] = "Ram";          // Assigns "Alice" to the first element

names[1] = "Piyu";            // Assigns "Bob" to the second element

names[2] = "Ganesh";        // Assigns "Charlie" to the third element

 

// Boolean array

boolean[] flags = new boolean[3];

flags[0] = true;             // Assigns true to the first element

flags[1] = false;            // Assigns false to the second element

flags[2] = true;             // Assigns true to the third element

      Declaration, Instantiation, and Initialization in One Line |:
For convenience, especially when you know all the values at the time of creation, you can declare, instantiate, and initialize an array in a single statement. Java automatically determines the size of the array based on the number of values provided.

      Syntax: dataType[] arrayName = {value1, value2, …, valueN};

            Examples:

 // Integer array of size 5

        int[] scores = {85, 92, 78, 65, 95};

 

        // String array of size 3

        String[] fruits = {"Apple", "Banana", "Cherry"};

 

        // Double array of size 3

        double[] temperatures = {23.5, 25.1, 22.9};

      Accessing Elements |:
To retrieve the value stored at a particular position in the array, you use its index.

      Syntax: arrayName[index]

            Examples:

 public class AccessArrayExample {

    public static void main(String[] args) {

 

        // Initialize arrays

        int[] scores = {85, 92, 78, 65, 95};

        String[] fruits = {"Apple", "Banana", "Cherry"};

 

        // Accessing elements using index

        int firstScore = scores[0];       // firstScore will be 85

        int thirdScore = scores[2];       // thirdScore will be 78

 

        String secondFruit = fruits[1];   // secondFruit will be "Banana"

        String firstFruit = fruits[0];    // firstFruit will be "Apple"

 

        // Printing accessed elements

        System.out.println("First Score: " + firstScore);

        System.out.println("Third Score: " + thirdScore);

        System.out.println("First Fruit: " + firstFruit);

        System.out.println("Second Fruit: " + secondFruit);

    }

}

            Important: Trying to access an index outside the array’s valid range (e.g., scores for an array of size 5) will result in an ArrayIndexOutOfBoundsException at runtime.

      Array Length |:
Every array in Java has a built-in length property (it’s not a method, so no parentheses) that returns the number of elements the array can hold. This is very useful for iterating over arrays.

      Syntax: arrayName.length

            Example:

 public class ArrayLengthExample {

    public static void main(String[] args) {

 

        // Declare and initialize an array

        int[] data = {1, 2, 3, 4, 5, 6, 7};

 

        // Accessing the length property

        System.out.println("The array has " + data.length + " elements.");

 

        // Using length in a loop

        System.out.println("Array elements:");

        for (int i = 0; i < data.length; i++) {

            System.out.println("Element at index " + i + ": " + data[i]);

        }

    }

}

      Iterating Over 1D Arrays |:
Looping through an array is a common operation. You can use a traditional for loop or an enhanced for loop (also known as a for-each loop).

      Using for loop:
This loop is suitable when you need to access the index of each element, or when you need to iterate only a portion of the array.

 public class IterateArrayExample {

    public static void main(String[] args) {

 

        // Initialize an integer array

        int[] scores = {85, 92, 78, 65, 95};

 

        // Iterate over the array using its length property

        for (int i = 0; i < scores.length; i++) {

            System.out.println("Score at index " + i + ": " + scores[i]);

        }

    }

}

Using Enhanced for loop (for-each loop):
This loop is simpler and more readable when you just need to process each element in the array and don’t need its index.

 public class EnhancedForLoopExample {

    public static void main(String[] args) {

 

        // Initialize an integer array

        int[] scores = {85, 92, 78, 65, 95};

 

        // Using enhanced for loop (for-each loop)

        System.out.println("Scores in the array:");

        for (int score : scores) {

            System.out.println(score);

        }

    }

}

1.11.3 Two-Dimensional (2D) Arrays

A two-dimensional array is an array of arrays, often visualized as a grid or a table with rows and columns. Each element in a 2D array is itself an array.

Concept |:
Think of a chessboard, a matrix in mathematics, or a spreadsheet. Each cell in this grid can hold a value. A 2D array is ideal for representing such tabular data.

Declaration |:
You add an extra set of square brackets to indicate a 2D array.

      Syntax 1: dataType[][] arrayName;

      Syntax 2: dataType arrayName[][];

            Examples:

 int[][] matrix;       // Declares a 2D integer array

String[][] students;  // Declares a 2D String array (e.g., for names and IDs)

Instantiation |:
When instantiating, you specify the number of rows and columns.

      Syntax: arrayName = new dataType[rows][cols];

            Example:

          // Declare a 2D array

        int[][] matrix;

 

        // Instantiate a 2D array with 3 rows and 4 columns

        matrix = new int[3][4];

            This creates 3 arrays, each capable of holding 4 int values.

Initialization |:

      Assigning values to individual elements: You use two indices: one for the row and one for the column.

      Syntax: arrayName[row][col] = value;

            Example:

 // Declare and instantiate a 2D array (3 rows, 4 columns)

        int[][] matrix = new int[3][4];

 

        // Assign values to specific elements

        matrix[0][0] = 1;  // First element (row 0, column 0)

        matrix[0][1] = 2;  // Element in row 0, column 1

        matrix[1][0] = 5;  // Element in row 1, column 0

Using nested loops for initialization: This is common for populating large 2D arrays or when values follow a pattern.

 public class IdentityMatrixExample {

    public static void main(String[] args) {

 

        // Instantiate a 2D array (3×3)

        int[][] identityMatrix = new int[3][3];

 

        // Populate the array using nested loops

        for (int i = 0; i < identityMatrix.length; i++) {          // Loop through rows

            for (int j = 0; j < identityMatrix[i].length; j++) {   // Loop through columns

                if (i == j) {

                    identityMatrix[i][j] = 1;  // Diagonal elements are 1

                } else {

                    identityMatrix[i][j] = 0;  // Other elements are 0

                }

            }

        }

 

        // Print the 2D array

        System.out.println("Identity Matrix:");

        for (int i = 0; i < identityMatrix.length; i++) {

            for (int j = 0; j < identityMatrix[i].length; j++) {

                System.out.print(identityMatrix[i][j] + " ");

            }

            System.out.println();

        }

    }

}

Direct initialization: Similar to 1D arrays, you can initialize a 2D array directly using nested curly braces.

      Syntax: dataType[][] arrayName = {{val1, val2}, {val3, val4}, …};

            Example:

         // Directly initializing a 2D integer array (3 rows, 3 columns)

        int[][] numbersGrid = {

            {10, 20, 30},

            {40, 50, 60},

            {70, 80, 90}

        };

Accessing Elements |:
You need both the row and column index to access an element.

      Syntax: arrayName[row][col]

            Example:

 // Accessing specific elements

        int value = numbersGrid[1][1]; // Row 1, Column 1 (second row, second column)

        System.out.println("Value at row 1, column 1: " + value);

 

        int firstElement = numbersGrid[0][0]; // Row 0, Column 0

        int lastElement = numbersGrid[2][2];  // Row 2, Column 2

        System.out.println("First element: " + firstElement);

        System.out.println("Last element: " + lastElement);

Iterating Over 2D Arrays |:
You typically use nested for loops to iterate over all elements of a 2D array. The outer loop iterates through the rows, and the inner loop iterates through the columns of the current row.

 public class Iterate2DArrayExample {

    public static void main(String[] args) {

 

        // Directly initializing a 2D array

        int[][] numbersGrid = {

            {10, 20, 30},

            {40, 50, 60},

            {70, 80, 90}

        };

 

        // Iterating over the 2D array using nested for loops

        System.out.println("2D Array Elements:");

        for (int i = 0; i < numbersGrid.length; i++) {            // Loop through rows

            for (int j = 0; j < numbersGrid[i].length; j++) {     // Loop through columns

                System.out.print(numbersGrid[i][j] + " ");

            }

            System.out.println(); // Move to the next line after each row

        }

    }

}

Ragged Arrays |:
Java allows for ragged (or jagged) arrays, where each row in a 2D array can have a different number of columns. This is possible because a 2D array is an array of arrays, and each inner array can be instantiated with a different size.

            Example:

 public class RaggedArrayExample {

    public static void main(String[] args) {

 

        // Declare a ragged array with 3 rows

        int[][] raggedArray = new int[3][];

 

        // Instantiate each row with different number of columns

        raggedArray[0] = new int[5];  // First row has 5 columns

        raggedArray[1] = new int[2];  // Second row has 2 columns

        raggedArray[2] = new int[4];  // Third row has 4 columns

 

        // Populate the array

        raggedArray[0][0] = 1;

        raggedArray[0][1] = 2;

        raggedArray[0][2] = 3;

        raggedArray[1][0] = 4;

        raggedArray[1][1] = 5;

        raggedArray[2][0] = 6;

        raggedArray[2][1] = 7;

        raggedArray[2][2] = 8;

        raggedArray[2][3] = 9;

 

        // Iterating and printing the ragged array

        System.out.println("Ragged Array:");

        for (int i = 0; i < raggedArray.length; i++) {

            for (int j = 0; j < raggedArray[i].length; j++) {

                System.out.print(raggedArray[i][j] + " ");

            }

            System.out.println();

        }

    }

}

Arrays are a powerful and essential part of Java programming, allowing you to manage collections of data efficiently.