4.3 Multi-dimensional Arrays
A multi-dimensional array is an array of arrays. While one-dimensional arrays represent a linear sequence, multi-dimensional arrays can represent tables, matrices, grids, or more complex data structures.
Types of Multi-dimensional Arrays
- Two-dimensional arrays (2D arrays) - Tables or matrices
- Three-dimensional arrays (3D arrays) - Cubes or 3D spaces
- Higher-dimensional arrays - More complex structures
- Jagged arrays - Arrays of arrays with different lengths
Two-Dimensional Arrays
A 2D array can be visualized as a table with rows and columns:
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Visual representation:
Row 0: [1][2][3]
Row 1: [4][5][6]
Row 2: [7][8][9]
Memory Representation
In Java, 2D arrays are implemented as arrays of arrays. Each row is a separate array object.
matrix → [0] → [1, 2, 3]
[1] → [4, 5, 6]
[2] → [7, 8, 9]
Declaration and Initialization
1. Declaration Only
// Syntax: dataType[][] arrayName;
int[][] matrix;
double[][] prices;
String[][] names;
2. Declaration with Memory Allocation
// Syntax: dataType[][] arrayName = new dataType[rows][columns];
int[][] matrix = new int[3][4]; // 3 rows, 4 columns
boolean[][] flags = new boolean[2][3]; // 2 rows, 3 columns
String[][] grid = new String[5][5]; // 5x5 grid
3. Direct Initialization with Values
// 2x3 matrix
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
// 3x2 array of strings
String[][] chessBoard = {
{"Rook", "Knight"},
{"Pawn", "Pawn"},
{"", "Bishop"}
};
// 2x2 array of booleans
boolean[][] switches = {
{true, false},
{false, true}
};
4. Step-by-step Initialization
// Declare
int[][] scores;
// Allocate memory for rows
scores = new int[3][4];
// Initialize individual elements
scores[0][0] = 85;
scores[0][1] = 92;
scores[0][2] = 78;
scores[0][3] = 90;
// ... and so on for other rows
5. Different Row Lengths (Jagged Arrays)
// Declaration with fixed rows, variable columns
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[2]; // First row has 2 columns
jaggedArray[1] = new int[4]; // Second row has 4 columns
jaggedArray[2] = new int[3]; // Third row has 3 columns
// Direct initialization of jagged array
int[][] triangle = {
{1},
{2, 3},
{4, 5, 6},
{7, 8, 9, 10}
};
Accessing Elements
Basic Element Access
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Access individual elements
int element1 = matrix[0][0]; // 1 (row 0, column 0)
int element2 = matrix[1][2]; // 6 (row 1, column 2)
int element3 = matrix[2][1]; // 8 (row 2, column 1)
// Modify elements
matrix[0][0] = 10; // Change 1 to 10
matrix[1][1] = 50; // Change 5 to 50
Using Variables as Indices
int[][] data = new int[4][3];
int row = 2, col = 1;
data[row][col] = 100; // Set element at row 2, column 1
System.out.println(data[1][2]); // Access element at row 1, column 2
Valid Index Range
int[][] grid = new int[3][4];
// Valid indices:
// rows: 0 to 2 (grid.length - 1)
// columns: 0 to 3 (grid[0].length - 1)
// These would cause ArrayIndexOutOfBoundsException:
// grid[3][0] // Row index out of bounds
// grid[0][4] // Column index out of bounds
// grid[-1][0] // Negative index
Iterating Through Multi-dimensional Arrays
1. Nested For Loops (Most Common)
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Row-major order (process rows first)
for (int i = 0; i < matrix.length; i++) { // For each row
for (int j = 0; j < matrix[i].length; j++) { // For each column in current row
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // New line after each row
}
// Output:
// 1 2 3
// 4 5 6
// 7 8 9
2. Enhanced For Loops (For-Each)
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Using enhanced for loops
for (int[] row : matrix) { // Each row is an int[]
for (int element : row) { // Each element in the row
System.out.print(element + " ");
}
System.out.println();
}
3. Column-major Iteration
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Process columns first
for (int j = 0; j < matrix[0].length; j++) { // For each column
for (int i = 0; i < matrix.length; i++) { // For each row in current column
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // New line after each column
}
// Output:
// 1 4 7
// 2 5 8
// 3 6 9
4. Iterating Jagged Arrays
int[][] jagged = {
{1, 2},
{3, 4, 5, 6},
{7},
{8, 9, 10}
};
for (int i = 0; i < jagged.length; i++) {
System.out.print("Row " + i + " (" + jagged[i].length + " elements): ");
for (int j = 0; j < jagged[i].length; j++) {
System.out.print(jagged[i][j] + " ");
}
System.out.println();
}
// Output:
// Row 0 (2 elements): 1 2
// Row 1 (4 elements): 3 4 5 6
// Row 2 (1 elements): 7
// Row 3 (3 elements): 8 9 10
Three-Dimensional Arrays
A 3D array can be visualized as a cube with layers, rows, and columns:
int[][][] cube = new int[2][3][4]; // 2 layers, 3 rows, 4 columns
Declaration and Initialization
// Method 1: Direct initialization
int[][][] cube = {
{ // Layer 0
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{ // Layer 1
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}
}
};
// Method 2: Step-by-step
int[][][] data = new int[2][3][2];
data[0][0][0] = 1;
data[0][0][1] = 2;
data[0][1][0] = 3;
// ... and so on
Iterating 3D Arrays
int[][][] cube = {
{{1, 2}, {3, 4}, {5, 6}},
{{7, 8}, {9, 10}, {11, 12}}
};
for (int i = 0; i < cube.length; i++) { // Layers
System.out.println("Layer " + i + ":");
for (int j = 0; j < cube[i].length; j++) { // Rows
for (int k = 0; k < cube[i][j].length; k++) { // Columns
System.out.print(cube[i][j][k] + " ");
}
System.out.println();
}
System.out.println();
}
Jagged Arrays
Jagged arrays are arrays of arrays where each sub-array can have a different length. They're memory-efficient when dealing with irregular data structures.
Creating Jagged Arrays
// Method 1: Step-by-step
int[][] jagged = new int[4][]; // 4 rows, columns unspecified
jagged[0] = new int[2]; // Row 0 has 2 columns
jagged[1] = new int[3]; // Row 1 has 3 columns
jagged[2] = new int[1]; // Row 2 has 1 column
jagged[3] = new int[4]; // Row 3 has 4 columns
// Method 2: Direct initialization
String[][] studentCourses = {
{"Math", "Physics"}, // Student 0: 2 courses
{"History", "English", "Art"}, // Student 1: 3 courses
{"Chemistry"}, // Student 2: 1 course
{"Biology", "Geography", "Music", "Drama"} // Student 3: 4 courses
};
Working with Jagged Arrays
// Initialize values
for (int i = 0; i < jagged.length; i++) {
for (int j = 0; j < jagged[i].length; j++) {
jagged[i][j] = (i + 1) * (j + 1);
}
}
// Print jagged array
for (int i = 0; i < jagged.length; i++) {
System.out.print("Row " + i + ": ");
for (int j = 0; j < jagged[i].length; j++) {
System.out.print(jagged[i][j] + " ");
}
System.out.println();
}
Common Operations
1. Matrix Addition
public class MatrixAddition {
public static void main(String[] args) {
int[][] matrixA = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[][] matrixB = {
{9, 8, 7},
{6, 5, 4},
{3, 2, 1}
};
int[][] result = new int[3][3];
// Add matrices
for (int i = 0; i < matrixA.length; i++) {
for (int j = 0; j < matrixA[i].length; j++) {
result[i][j] = matrixA[i][j] + matrixB[i][j];
}
}
// Print result
System.out.println("Matrix A + Matrix B:");
printMatrix(result);
}
public static void printMatrix(int[][] matrix) {
for (int[] row : matrix) {
for (int element : row) {
System.out.print(element + " ");
}
System.out.println();
}
}
}
2. Matrix Multiplication
public class MatrixMultiplication {
public static void main(String[] args) {
int[][] matrixA = {
{1, 2, 3},
{4, 5, 6}
}; // 2x3 matrix
int[][] matrixB = {
{7, 8},
{9, 10},
{11, 12}
}; // 3x2 matrix
// Result will be 2x2 matrix
int[][] result = new int[2][2];
// Multiply matrices
for (int i = 0; i < matrixA.length; i++) { // Rows of A
for (int j = 0; j < matrixB[0].length; j++) { // Columns of B
for (int k = 0; k < matrixA[0].length; k++) { // Columns of A = Rows of B
result[i][j] += matrixA[i][k] * matrixB[k][j];
}
}
}
System.out.println("Matrix A * Matrix B:");
printMatrix(result);
}
public static void printMatrix(int[][] matrix) {
for (int[] row : matrix) {
for (int element : row) {
System.out.print(element + " ");
}
System.out.println();
}
}
}
3. Transpose of a Matrix
public class MatrixTranspose {
public static void main(String[] args) {
int[][] original = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[][] transpose = new int[3][3];
// Create transpose
for (int i = 0; i < original.length; i++) {
for (int j = 0; j < original[i].length; j++) {
transpose[j][i] = original[i][j];
}
}
System.out.println("Original matrix:");
printMatrix(original);
System.out.println("Transpose matrix:");
printMatrix(transpose);
}
public static void printMatrix(int[][] matrix) {
for (int[] row : matrix) {
for (int element : row) {
System.out.print(element + " ");
}
System.out.println();
}
}
}
4. Finding Maximum in Each Row
public class RowMaximum {
public static void main(String[] args) {
int[][] matrix = {
{5, 12, 3, 8},
{15, 2, 9, 4},
{7, 11, 6, 13}
};
for (int i = 0; i < matrix.length; i++) {
int max = matrix[i][0];
for (int j = 1; j < matrix[i].length; j++) {
if (matrix[i][j] > max) {
max = matrix[i][j];
}
}
System.out.println("Maximum in row " + i + ": " + max);
}
}
}
Real-world Applications
Example 1: Student Grade Management
public class GradeManagement {
public static void main(String[] args) {
// 4 students, each with grades for 3 subjects
int[][] grades = {
{85, 92, 78}, // Student 0: Math, Science, English
{76, 88, 95}, // Student 1
{90, 87, 83}, // Student 2
{79, 91, 84} // Student 3
};
String[] subjects = {"Math", "Science", "English"};
String[] students = {"Alice", "Bob", "Charlie", "Diana"};
// Calculate average per student
System.out.println("Student Averages:");
for (int i = 0; i < grades.length; i++) {
int sum = 0;
for (int j = 0; j < grades[i].length; j++) {
sum += grades[i][j];
}
double average = (double) sum / grades[i].length;
System.out.printf("%s: %.2f\n", students[i], average);
}
// Calculate average per subject
System.out.println("\nSubject Averages:");
for (int j = 0; j < grades[0].length; j++) {
int sum = 0;
for (int i = 0; i < grades.length; i++) {
sum += grades[i][j];
}
double average = (double) sum / grades.length;
System.out.printf("%s: %.2f\n", subjects[j], average);
}
}
}
Example 2: Tic-Tac-Toe Board
public class TicTacToe {
public static void main(String[] args) {
char[][] board = {
{' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '}
};
// Make some moves
board[0][0] = 'X';
board[1][1] = 'O';
board[2][2] = 'X';
board[0][2] = 'O';
board[2][0] = 'X';
// Display board
System.out.println("Tic-Tac-Toe Board:");
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
System.out.print(board[i][j]);
if (j < board[i].length - 1) {
System.out.print(" | ");
}
}
System.out.println();
if (i < board.length - 1) {
System.out.println("---------");
}
}
}
}
Example 3: Image Processing (Pixel Matrix)
public class ImageProcessor {
public static void main(String[] args) {
// Represent a 4x4 grayscale image (0-255)
int[][] image = {
{100, 120, 140, 160},
{110, 130, 150, 170},
{105, 125, 145, 165},
{115, 135, 155, 175}
};
// Apply brightness adjustment
int brightness = 20;
int[][] brightenedImage = new int[4][4];
for (int i = 0; i < image.length; i++) {
for (int j = 0; j < image[i].length; j++) {
brightenedImage[i][j] = Math.min(255, image[i][j] + brightness);
}
}
System.out.println("Original Image:");
printMatrix(image);
System.out.println("\nBrightened Image:");
printMatrix(brightenedImage);
}
public static void printMatrix(int[][] matrix) {
for (int[] row : matrix) {
for (int pixel : row) {
System.out.print(pixel + " ");
}
System.out.println();
}
}
}
Common Mistakes and Best Practices
Common Mistakes
Assuming rectangular arrays
javaint[][] matrix = new int[3][4]; // Wrong: assuming all rows have same length as first row for (int j = 0; j < matrix[0].length; j++) { // Works only for rectangular arrays // ... }
Index order confusion
javaint[][] matrix = new int[2][3]; // Wrong: matrix[column][row] // Correct: matrix[row][column]
Forgetting to initialize inner arrays
javaint[][] jagged = new int[3][]; // Wrong: jagged[0][0] = 1; (NullPointerException) // Correct: jagged[0] = new int[2]; then jagged[0][0] = 1;
Best Practices
Always check array dimensions
java// Safe iteration for any 2D array for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { // Process array[i][j] } }
Use descriptive variable names for indices
javafor (int row = 0; row < matrix.length; row++) { for (int col = 0; col < matrix[row].length; col++) { // More readable than i and j } }
Validate dimensions before operations
java// Before matrix multiplication if (matrixA[0].length != matrixB.length) { System.out.println("Cannot multiply: dimension mismatch"); return; }
Summary
- Multi-dimensional arrays are arrays of arrays
- 2D arrays represent tables/matrices with rows and columns
- 3D arrays add a third dimension (layers)
- Jagged arrays have rows of different lengths
- Use nested loops for iteration
- Always check array bounds and dimensions
- Multi-dimensional arrays are essential for representing complex data structures
In the next section, we'll explore string manipulation and the various methods available for working with text data.