Array 2 dimensi atau matrix adalah struktur data fundamental yang sangat penting dalam pemrograman Java. Bagi yang baru memulai, sebaiknya pahami dulu tutorial java untuk pemula sebelum mempelajari konsep array multidimensi ini.
Dalam tutorial ini, kita akan mempelajari cara mendeklarasikan, menginisialisasi, dan memanipulasi array 2 dimensi dengan berbagai contoh program praktis yang dapat langsung diimplementasikan.
Konsep Dasar Array 2 Dimensi
Sebelum masuk ke implementasi, penting untuk memahami konsep array dalam java secara menyeluruh. Array 2D dapat dibayangkan sebagai tabel dengan baris dan kolom.
Karakteristik Array 2D
- Struktur: Baris dan kolom
- Indeks: [baris][kolom]
- Memory: Continuous allocation
- Type: Homogeneous data
Kegunaan Array 2D
- Representasi matrix matematika
- Game board (catur, tic-tac-toe)
- Image processing (pixel data)
- Tabel data dan spreadsheet
š” Visualisasi Array 2D
Array 2D seperti int[][] matrix = new int[3][4] dapat divisualisasikan sebagai:
Deklarasi dan Inisialisasi Array 2D
Ada beberapa cara untuk mendeklarasikan dan menginisialisasi array 2 dimensi dalam Java.
Berbagai Cara Deklarasi Array 2D:
public class Array2DDeclaration {
public static void main(String[] args) {
// 1. Deklarasi dengan ukuran tetap
int[][] matrix1 = new int[3][4]; // 3 baris, 4 kolom
// 2. Deklarasi dengan inisialisasi langsung
int[][] matrix2 = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 3. Deklarasi dengan inisialisasi bertahap
int[][] matrix3 = new int[2][3];
matrix3[0][0] = 10;
matrix3[0][1] = 20;
matrix3[0][2] = 30;
matrix3[1][0] = 40;
matrix3[1][1] = 50;
matrix3[1][2] = 60;
// 4. Jagged Array (array dengan panjang baris berbeda)
int[][] jaggedArray = {
{1, 2},
{3, 4, 5, 6},
{7, 8, 9}
};
// 5. Deklarasi dengan new operator
int[][] matrix4 = new int[][] {
{100, 200},
{300, 400},
{500, 600}
};
// Menampilkan matrix2
System.out.println("Matrix 2 (3x4):");
for (int i = 0; i < matrix2.length; i++) {
for (int j = 0; j < matrix2[i].length; j++) {
System.out.print(matrix2[i][j] + "\t");
}
System.out.println();
}
// Menampilkan jagged array
System.out.println("\nJagged Array:");
for (int i = 0; i < jaggedArray.length; i++) {
for (int j = 0; j < jaggedArray[i].length; j++) {
System.out.print(jaggedArray[i][j] + "\t");
}
System.out.println();
}
}
}
Contoh 1: Operasi Dasar Array 2D
Program ini mendemonstrasikan operasi-operasi dasar pada array 2D seperti input, output, dan manipulasi data. Pemahaman tentang perulangan for loop java sangat penting untuk bagian ini.
Operasi Dasar Array 2D:
import java.util.Scanner;
public class Array2DBasicOperations {
// Method untuk input array 2D dari user
public static void inputArray(int[][] arr, Scanner scanner) {
System.out.println("Masukkan elemen array:");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print("Element [" + i + "][" + j + "]: ");
arr[i][j] = scanner.nextInt();
}
}
}
// Method untuk menampilkan array 2D
public static void displayArray(int[][] arr, String title) {
System.out.println("\n" + title + ":");
System.out.println("+" + "-".repeat(arr[0].length * 8) + "+");
for (int i = 0; i < arr.length; i++) {
System.out.print("|");
for (int j = 0; j < arr[i].length; j++) {
System.out.printf("%6d ", arr[i][j]);
}
System.out.println("|");
}
System.out.println("+" + "-".repeat(arr[0].length * 8) + "+");
}
// Method untuk mencari nilai maksimum
public static int findMax(int[][] arr) {
int max = arr[0][0];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) { if (arr[i][j] > max) {
max = arr[i][j];
}
}
}
return max;
}
// Method untuk mencari nilai minimum
public static int findMin(int[][] arr) {
int min = arr[0][0];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] < min) {
min = arr[i][j];
}
}
}
return min;
}
// Method untuk menghitung sum semua elemen
public static int calculateSum(int[][] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum += arr[i][j];
}
}
return sum;
}
// Method untuk menghitung rata-rata
public static double calculateAverage(int[][] arr) {
int sum = calculateSum(arr);
int totalElements = arr.length * arr[0].length;
return (double) sum / totalElements;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("=== PROGRAM OPERASI ARRAY 2D ===");
// Input ukuran array
System.out.print("Masukkan jumlah baris: ");
int rows = scanner.nextInt();
System.out.print("Masukkan jumlah kolom: ");
int cols = scanner.nextInt();
// Buat array 2D
int[][] matrix = new int[rows][cols];
// Input data
inputArray(matrix, scanner);
// Tampilkan array
displayArray(matrix, "Array 2D yang diinput");
// Hitung dan tampilkan statistik
System.out.println("\n=== STATISTIK ARRAY ===");
System.out.println("Nilai Maksimum: " + findMax(matrix));
System.out.println("Nilai Minimum: " + findMin(matrix));
System.out.println("Jumlah semua elemen: " + calculateSum(matrix));
System.out.printf("Rata-rata: %.2f%n", calculateAverage(matrix));
scanner.close();
}
}
Contoh 2: Operasi Matrix Matematika
Program ini mengimplementasikan operasi matematika dasar pada matrix seperti penjumlahan, pengurangan, dan perkalian.
Operasi Matrix Matematika:
public class MatrixOperations {
// Method untuk penjumlahan matrix
public static int[][] addMatrix(int[][] matrix1, int[][] matrix2) {
int rows = matrix1.length;
int cols = matrix1[0].length;
int[][] result = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return result;
}
// Method untuk pengurangan matrix
public static int[][] subtractMatrix(int[][] matrix1, int[][] matrix2) {
int rows = matrix1.length;
int cols = matrix1[0].length;
int[][] result = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result[i][j] = matrix1[i][j] - matrix2[i][j];
}
}
return result;
}
// Method untuk perkalian matrix
public static int[][] multiplyMatrix(int[][] matrix1, int[][] matrix2) {
int rows1 = matrix1.length;
int cols1 = matrix1[0].length;
int cols2 = matrix2[0].length;
int[][] result = new int[rows1][cols2];
for (int i = 0; i < rows1; i++) {
for (int j = 0; j < cols2; j++) {
for (int k = 0; k < cols1; k++) {
result[i][j] += matrix1[i][k] * matrix2[k][j];
}
}
}
return result;
}
// Method untuk transpose matrix
public static int[][] transposeMatrix(int[][] matrix) {
int rows = matrix.length;
int cols = matrix[0].length;
int[][] result = new int[cols][rows];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result[j][i] = matrix[i][j];
}
}
return result;
}
// Method untuk menampilkan matrix dengan format rapi
public static void printMatrix(int[][] matrix, String title) {
System.out.println("\n" + title + ":");
for (int i = 0; i < matrix.length; i++) {
System.out.print("[ ");
for (int j = 0; j < matrix[i].length; j++) {
System.out.printf("%4d ", matrix[i][j]);
}
System.out.println("]");
}
}
// Method untuk cek apakah matrix bisa dikalikan
public static boolean canMultiply(int[][] matrix1, int[][] matrix2) {
return matrix1[0].length == matrix2.length;
}
public static void main(String[] args) {
System.out.println("=== OPERASI MATRIX MATEMATIKA ===");
// Matrix A (3x3)
int[][] matrixA = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Matrix B (3x3)
int[][] matrixB = {
{9, 8, 7},
{6, 5, 4},
{3, 2, 1}
};
// Matrix C (3x2) untuk perkalian
int[][] matrixC = {
{1, 2},
{3, 4},
{5, 6}
};
// Tampilkan matrix awal
printMatrix(matrixA, "Matrix A");
printMatrix(matrixB, "Matrix B");
printMatrix(matrixC, "Matrix C");
// Operasi penjumlahan
int[][] sum = addMatrix(matrixA, matrixB);
printMatrix(sum, "A + B");
// Operasi pengurangan
int[][] difference = subtractMatrix(matrixA, matrixB);
printMatrix(difference, "A - B");
// Operasi perkalian
if (canMultiply(matrixA, matrixC)) {
int[][] product = multiplyMatrix(matrixA, matrixC);
printMatrix(product, "A Ć C");
} else {
System.out.println("Matrix A dan C tidak bisa dikalikan!");
}
// Transpose matrix
int[][] transposeA = transposeMatrix(matrixA);
printMatrix(transposeA, "Transpose A");
// Demonstrasi perkalian matrix persegi
int[][] squareProduct = multiplyMatrix(matrixA, matrixB);
printMatrix(squareProduct, "A Ć B");
}
}
Contoh 3: Sistem Nilai Siswa
Program ini menggunakan array 2D untuk menyimpan dan mengolah data nilai siswa dalam berbagai mata pelajaran.
Sistem Nilai Siswa:
import java.util.Scanner;
public class StudentGradeSystem {
private static String[] studentNames;
private static String[] subjects;
private static int[][] grades;
// Method untuk input data siswa dan nilai
public static void inputGrades(Scanner scanner) {
System.out.print("Masukkan jumlah siswa: ");
int numStudents = scanner.nextInt();
System.out.print("Masukkan jumlah mata pelajaran: ");
int numSubjects = scanner.nextInt();
studentNames = new String[numStudents];
subjects = new String[numSubjects];
grades = new int[numStudents][numSubjects];
scanner.nextLine(); // consume newline
// Input nama siswa
System.out.println("\n=== INPUT NAMA SISWA ===");
for (int i = 0; i < numStudents; i++) {
System.out.print("Nama siswa ke-" + (i + 1) + ": ");
studentNames[i] = scanner.nextLine();
}
// Input nama mata pelajaran
System.out.println("\n=== INPUT MATA PELAJARAN ===");
for (int i = 0; i < numSubjects; i++) {
System.out.print("Mata pelajaran ke-" + (i + 1) + ": ");
subjects[i] = scanner.nextLine();
}
// Input nilai
System.out.println("\n=== INPUT NILAI ===");
for (int i = 0; i < numStudents; i++) {
System.out.println("Nilai untuk " + studentNames[i] + ":");
for (int j = 0; j < numSubjects; j++) {
do {
System.out.print(" " + subjects[j] + " (0-100): ");
grades[i][j] = scanner.nextInt();
if (grades[i][j] < 0 || grades[i][j] > 100) {
System.out.println(" Nilai harus antara 0-100!");
}
} while (grades[i][j] < 0 || grades[i][j] > 100);
}
}
}
// Method untuk menampilkan tabel nilai
public static void displayGradeTable() {
System.out.println("\n" + "=".repeat(80));
System.out.println(" TABEL NILAI SISWA");
System.out.println("=".repeat(80));
// Header tabel
System.out.printf("%-20s", "NAMA SISWA");
for (String subject : subjects) {
System.out.printf("%-12s", subject.toUpperCase());
}
System.out.printf("%-10s%-8s%n", "RATA2", "GRADE");
System.out.println("-".repeat(80));
// Data siswa
for (int i = 0; i < studentNames.length; i++) {
System.out.printf("%-20s", studentNames[i]);
int sum = 0;
for (int j = 0; j < subjects.length; j++) { System.out.printf("%-12d", grades[i][j]); sum += grades[i][j]; } double average = (double) sum / subjects.length; String grade = getLetterGrade(average); System.out.printf("%-10.1f%-8s%n", average, grade); } System.out.println("=".repeat(80)); } // Method untuk konversi nilai ke huruf public static String getLetterGrade(double average) { if (average >= 90) return "A";
else if (average >= 80) return "B";
else if (average >= 70) return "C";
else if (average >= 60) return "D";
else return "E";
}
// Method untuk menghitung statistik per mata pelajaran
public static void displaySubjectStatistics() {
System.out.println("\n" + "=".repeat(60));
System.out.println(" STATISTIK PER MATA PELAJARAN");
System.out.println("=".repeat(60));
System.out.printf("%-15s%-10s%-10s%-10s%-10s%n",
"MATA PELAJARAN", "RATA2", "MAX", "MIN", "LULUS");
System.out.println("-".repeat(60));
for (int j = 0; j < subjects.length; j++) {
int sum = 0, max = grades[0][j], min = grades[0][j], passed = 0;
for (int i = 0; i < studentNames.length; i++) { sum += grades[i][j]; if (grades[i][j] > max) max = grades[i][j];
if (grades[i][j] < min) min = grades[i][j]; if (grades[i][j] >= 70) passed++;
}
double average = (double) sum / studentNames.length;
System.out.printf("%-15s%-10.1f%-10d%-10d%-10d%n",
subjects[j], average, max, min, passed);
}
System.out.println("=".repeat(60));
}
// Method untuk mencari siswa terbaik
public static void findTopStudent() {
double maxAverage = 0;
int topStudentIndex = 0;
for (int i = 0; i < studentNames.length; i++) {
int sum = 0;
for (int j = 0; j < subjects.length; j++) { sum += grades[i][j]; } double average = (double) sum / subjects.length; if (average > maxAverage) {
maxAverage = average;
topStudentIndex = i;
}
}
System.out.println("\nš SISWA TERBAIK:");
System.out.println("Nama: " + studentNames[topStudentIndex]);
System.out.printf("Rata-rata: %.2f%n", maxAverage);
System.out.println("Grade: " + getLetterGrade(maxAverage));
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("=== SISTEM PENGELOLAAN NILAI SISWA ===");
inputGrades(scanner);
displayGradeTable();
displaySubjectStatistics();
findTopStudent();
scanner.close();
}
}
Contoh 4: Game Tic-Tac-Toe
Implementasi game Tic-Tac-Toe menggunakan array 2D untuk merepresentasikan papan permainan.
Game Tic-Tac-Toe:
import java.util.Scanner;
public class TicTacToe {
private static char[][] board = new char[3][3];
private static char currentPlayer = 'X';
// Method untuk inisialisasi papan
public static void initializeBoard() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = ' ';
}
}
}
// Method untuk menampilkan papan
public static void displayBoard() {
System.out.println("\n 0 1 2");
for (int i = 0; i < 3; i++) {
System.out.print(i + " ");
for (int j = 0; j < 3; j++) {
System.out.print(" " + board[i][j] + " ");
if (j < 2) System.out.print("|");
}
System.out.println();
if (i < 2) System.out.println(" -----------"); } System.out.println(); } // Method untuk cek apakah posisi valid public static boolean isValidMove(int row, int col) { return row >= 0 && row < 3 && col >= 0 && col < 3 && board[row][col] == ' ';
}
// Method untuk melakukan move
public static void makeMove(int row, int col) {
board[row][col] = currentPlayer;
}
// Method untuk cek pemenang
public static boolean checkWinner() {
// Cek baris
for (int i = 0; i < 3; i++) {
if (board[i][0] == currentPlayer &&
board[i][1] == currentPlayer &&
board[i][2] == currentPlayer) {
return true;
}
}
// Cek kolom
for (int j = 0; j < 3; j++) {
if (board[0][j] == currentPlayer &&
board[1][j] == currentPlayer &&
board[2][j] == currentPlayer) {
return true;
}
}
// Cek diagonal
if (board[0][0] == currentPlayer &&
board[1][1] == currentPlayer &&
board[2][2] == currentPlayer) {
return true;
}
if (board[0][2] == currentPlayer &&
board[1][1] == currentPlayer &&
board[2][0] == currentPlayer) {
return true;
}
return false;
}
// Method untuk cek apakah papan penuh (draw)
public static boolean isBoardFull() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == ' ') {
return false;
}
}
}
return true;
}
// Method untuk ganti pemain
public static void switchPlayer() {
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
}
// Method untuk menampilkan statistik game
public static void displayGameStats() {
int xCount = 0, oCount = 0, emptyCount = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == 'X') xCount++;
else if (board[i][j] == 'O') oCount++;
else emptyCount++;
}
}
System.out.println("=== STATISTIK GAME ===");
System.out.println("X: " + xCount + " moves");
System.out.println("O: " + oCount + " moves");
System.out.println("Empty: " + emptyCount + " cells");
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("=== WELCOME TO TIC-TAC-TOE ===");
System.out.println("Player X starts first!");
System.out.println("Enter row and column (0-2) to make a move.");
initializeBoard();
while (true) {
displayBoard();
System.out.println("Player " + currentPlayer + "'s turn");
int row, col;
// Input dengan validasi
do {
System.out.print("Enter row (0-2): ");
row = scanner.nextInt();
System.out.print("Enter column (0-2): ");
col = scanner.nextInt();
if (!isValidMove(row, col)) {
System.out.println("Invalid move! Try again.");
}
} while (!isValidMove(row, col));
// Lakukan move
makeMove(row, col);
// Cek pemenang
if (checkWinner()) {
displayBoard();
System.out.println("š Player " + currentPlayer + " wins!");
displayGameStats();
break;
}
// Cek draw
if (isBoardFull()) {
displayBoard();
System.out.println("š¤ It's a draw!");
displayGameStats();
break;
}
// Ganti pemain
switchPlayer();
}
scanner.close();
}
}
Contoh 5: Simulasi Image Processing
Program ini mensimulasikan operasi dasar image processing menggunakan array 2D untuk merepresentasikan pixel.
Simulasi Image Processing:
import java.util.Random;
public class ImageProcessingSimulation {
// Method untuk generate random image (grayscale 0-255)
public static int[][] generateRandomImage(int width, int height) {
Random random = new Random();
int[][] image = new int[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
image[i][j] = random.nextInt(256); // 0-255
}
}
return image;
}
// Method untuk menampilkan image sebagai ASCII art
public static void displayImage(int[][] image, String title) {
System.out.println("\n" + title + ":");
System.out.println("+" + "-".repeat(image[0].length * 2) + "+");
for (int i = 0; i < image.length; i++) {
System.out.print("|");
for (int j = 0; j < image[i].length; j++) {
// Convert grayscale to ASCII character
char pixel = getASCIIChar(image[i][j]);
System.out.print(pixel + " ");
}
System.out.println("|");
}
System.out.println("+" + "-".repeat(image[0].length * 2) + "+");
}
// Method untuk konversi nilai grayscale ke ASCII
public static char getASCIIChar(int value) {
if (value < 32) return '@';
else if (value < 64) return '#';
else if (value < 96) return '*';
else if (value < 128) return '+';
else if (value < 160) return '=';
else if (value < 192) return '-';
else if (value < 224) return '.';
else return ' ';
}
// Method untuk brightness adjustment
public static int[][] adjustBrightness(int[][] image, int adjustment) {
int height = image.length;
int width = image[0].length;
int[][] result = new int[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int newValue = image[i][j] + adjustment;
// Clamp values between 0-255
result[i][j] = Math.max(0, Math.min(255, newValue));
}
}
return result;
}
// Method untuk contrast adjustment
public static int[][] adjustContrast(int[][] image, double factor) {
int height = image.length;
int width = image[0].length;
int[][] result = new int[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int newValue = (int) ((image[i][j] - 128) * factor + 128);
result[i][j] = Math.max(0, Math.min(255, newValue));
}
}
return result;
}
// Method untuk blur effect (simple averaging)
public static int[][] applyBlur(int[][] image) {
int height = image.length;
int width = image[0].length;
int[][] result = new int[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int sum = 0;
int count = 0;
// Check 3x3 neighborhood
for (int di = -1; di <= 1; di++) {
for (int dj = -1; dj <= 1; dj++) { int ni = i + di; int nj = j + dj; if (ni >= 0 && ni < height && nj >= 0 && nj < width) {
sum += image[ni][nj];
count++;
}
}
}
result[i][j] = sum / count;
}
}
return result;
}
// Method untuk edge detection (simple)
public static int[][] detectEdges(int[][] image) {
int height = image.length;
int width = image[0].length;
int[][] result = new int[height][width];
for (int i = 1; i < height - 1; i++) {
for (int j = 1; j < width - 1; j++) {
// Sobel operator (simplified)
int gx = -image[i-1][j-1] + image[i-1][j+1] +
-2*image[i][j-1] + 2*image[i][j+1] +
-image[i+1][j-1] + image[i+1][j+1];
int gy = -image[i-1][j-1] - 2*image[i-1][j] - image[i-1][j+1] +
image[i+1][j-1] + 2*image[i+1][j] + image[i+1][j+1];
int magnitude = (int) Math.sqrt(gx*gx + gy*gy);
result[i][j] = Math.min(255, magnitude);
}
}
return result;
}
// Method untuk histogram calculation
public static void displayHistogram(int[][] image) {
int[] histogram = new int[256];
// Count pixel values
for (int i = 0; i < image.length; i++) {
for (int j = 0; j < image[i].length; j++) {
histogram[image[i][j]]++;
}
}
System.out.println("\n=== HISTOGRAM (simplified) ===");
System.out.println("Range\tCount\tBar");
System.out.println("-".repeat(30));
// Group into ranges for display
for (int range = 0; range < 8; range++) {
int count = 0;
int start = range * 32;
int end = start + 31;
for (int i = start; i <= end && i < 256; i++) {
count += histogram[i];
}
System.out.printf("%d-%d\t%d\t", start, end, count);
// Draw simple bar
int barLength = count / 5; // Scale down
for (int i = 0; i < barLength && i < 20; i++) {
System.out.print("ā");
}
System.out.println();
}
}
public static void main(String[] args) {
System.out.println("=== IMAGE PROCESSING SIMULATION ===");
// Generate sample image
int[][] originalImage = generateRandomImage(8, 6);
// Display original
displayImage(originalImage, "Original Image");
displayHistogram(originalImage);
// Brightness adjustment
int[][] brighterImage = adjustBrightness(originalImage, 50);
displayImage(brighterImage, "Brighter Image (+50)");
// Contrast adjustment
int[][] contrastImage = adjustContrast(originalImage, 1.5);
displayImage(contrastImage, "Higher Contrast (1.5x)");
// Blur effect
int[][] blurredImage = applyBlur(originalImage);
displayImage(blurredImage, "Blurred Image");
// Edge detection
int[][] edgeImage = detectEdges(originalImage);
displayImage(edgeImage, "Edge Detection");
System.out.println("\n=== PROCESSING COMPLETE ===");
System.out.println("Image dimensions: " + originalImage[0].length + "x" + originalImage.length);
System.out.println("Total pixels: " + (originalImage.length * originalImage[0].length));
}
}
Contoh 6: Sistem Reservasi Tempat Duduk
Program ini mengimplementasikan sistem reservasi tempat duduk menggunakan array 2D untuk bioskop atau auditorium.
Sistem Reservasi Tempat Duduk:
import java.util.Scanner;
public class SeatReservationSystem {
private static char[][] seats;
private static int rows, cols;
private static int totalSeats, reservedSeats;
// Method untuk inisialisasi sistem
public static void initializeSeating(int numRows, int numCols) {
rows = numRows;
cols = numCols;
seats = new char[rows][cols];
totalSeats = rows * cols;
reservedSeats = 0;
// Initialize all seats as available ('O')
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
seats[i][j] = 'O'; // O = Available
}
}
}
// Method untuk menampilkan layout tempat duduk
public static void displaySeating() {
System.out.println("\n" + "=".repeat(50));
System.out.println(" LAYOUT TEMPAT DUDUK");
System.out.println("=".repeat(50));
System.out.println("Legend: O = Available, X = Reserved");
System.out.println("-".repeat(50));
// Header kolom
System.out.print(" ");
for (int j = 0; j < cols; j++) {
System.out.printf("%3d", j + 1);
}
System.out.println();
// Baris tempat duduk
for (int i = 0; i < rows; i++) {
System.out.printf("%2c ", 'A' + i); // Row labels A, B, C, etc.
for (int j = 0; j < cols; j++) {
System.out.printf(" %c ", seats[i][j]);
}
System.out.println();
}
System.out.println("-".repeat(50));
System.out.println("Available: " + (totalSeats - reservedSeats) +
" | Reserved: " + reservedSeats +
" | Total: " + totalSeats);
System.out.println("=".repeat(50));
}
// Method untuk reservasi tempat duduk
public static boolean reserveSeat(int row, int col) {
if (row < 0 || row >= rows || col < 0 || col >= cols) {
System.out.println("ā Invalid seat position!");
return false;
}
if (seats[row][col] == 'X') {
System.out.println("ā Seat " + (char)('A' + row) + (col + 1) +
" is already reserved!");
return false;
}
seats[row][col] = 'X';
reservedSeats++;
System.out.println("ā
Seat " + (char)('A' + row) + (col + 1) +
" reserved successfully!");
return true;
}
// Method untuk cancel reservasi
public static boolean cancelReservation(int row, int col) {
if (row < 0 || row >= rows || col < 0 || col >= cols) {
System.out.println("ā Invalid seat position!");
return false;
}
if (seats[row][col] == 'O') {
System.out.println("ā Seat " + (char)('A' + row) + (col + 1) +
" is not reserved!");
return false;
}
seats[row][col] = 'O';
reservedSeats--;
System.out.println("ā
Reservation for seat " + (char)('A' + row) +
(col + 1) + " cancelled successfully!");
return true;
}
// Method untuk mencari tempat duduk kosong berurutan
public static void findConsecutiveSeats(int numSeats) {
System.out.println("\nš Searching for " + numSeats +
" consecutive available seats...");
boolean found = false;
// Search row by row
for (int i = 0; i < rows && !found; i++) {
for (int j = 0; j <= cols - numSeats; j++) {
boolean available = true;
// Check if consecutive seats are available
for (int k = 0; k < numSeats; k++) {
if (seats[i][j + k] == 'X') {
available = false;
break;
}
}
if (available) {
System.out.print("ā
Found consecutive seats: ");
for (int k = 0; k < numSeats; k++) {
System.out.print((char)('A' + i) + (j + k + 1));
if (k < numSeats - 1) System.out.print(", ");
}
System.out.println();
found = true;
break;
}
}
}
if (!found) {
System.out.println("ā No " + numSeats +
" consecutive seats available.");
}
}
// Method untuk statistik per baris
public static void displayRowStatistics() {
System.out.println("\nš STATISTIK PER BARIS:");
System.out.println("-".repeat(40));
System.out.printf("%-5s%-12s%-12s%-10s%n",
"Row", "Available", "Reserved", "% Full");
System.out.println("-".repeat(40));
for (int i = 0; i < rows; i++) {
int available = 0, reserved = 0;
for (int j = 0; j < cols; j++) {
if (seats[i][j] == 'O') available++;
else reserved++;
}
double percentage = (double) reserved / cols * 100;
System.out.printf("%-5c%-12d%-12d%-10.1f%%%n",
'A' + i, available, reserved, percentage);
}
System.out.println("-".repeat(40));
}
// Method untuk auto-reserve best seats
public static void autoReserveBestSeats(int numSeats) {
System.out.println("\nšÆ Auto-reserving " + numSeats + " best seats...");
// Priority: middle rows, middle columns
int centerRow = rows / 2;
int centerCol = cols / 2;
int reserved = 0;
// Try to reserve seats near center
for (int distance = 0; distance < Math.max(rows, cols) && reserved < numSeats; distance++) {
for (int i = Math.max(0, centerRow - distance);
i <= Math.min(rows - 1, centerRow + distance) && reserved < numSeats; i++) {
for (int j = Math.max(0, centerCol - distance);
j <= Math.min(cols - 1, centerCol + distance) && reserved < numSeats; j++) {
if (seats[i][j] == 'O') {
seats[i][j] = 'X';
reservedSeats++;
reserved++;
System.out.println("ā
Auto-reserved seat: " +
(char)('A' + i) + (j + 1));
}
}
}
}
if (reserved < numSeats) {
System.out.println("ā ļø Only " + reserved + " seats could be reserved.");
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("=== SISTEM RESERVASI TEMPAT DUDUK ===");
// Setup seating
System.out.print("Masukkan jumlah baris: ");
int numRows = scanner.nextInt();
System.out.print("Masukkan jumlah kolom: ");
int numCols = scanner.nextInt();
initializeSeating(numRows, numCols);
int choice;
do {
System.out.println("\n=== MENU ===");
System.out.println("1. Tampilkan Layout");
System.out.println("2. Reservasi Tempat Duduk");
System.out.println("3. Cancel Reservasi");
System.out.println("4. Cari Tempat Duduk Berurutan");
System.out.println("5. Auto-Reserve Best Seats");
System.out.println("6. Statistik Per Baris");
System.out.println("0. Keluar");
System.out.print("Pilih menu: ");
choice = scanner.nextInt();
switch (choice) {
case 1:
displaySeating();
break;
case 2:
displaySeating();
System.out.print("Masukkan baris (A, B, C, ...): ");
char rowChar = scanner.next().toUpperCase().charAt(0);
System.out.print("Masukkan kolom (1, 2, 3, ...): ");
int colNum = scanner.nextInt();
int rowIndex = rowChar - 'A';
int colIndex = colNum - 1;
reserveSeat(rowIndex, colIndex);
break;
case 3:
displaySeating();
System.out.print("Masukkan baris untuk cancel (A, B, C, ...): ");
rowChar = scanner.next().toUpperCase().charAt(0);
System.out.print("Masukkan kolom untuk cancel (1, 2, 3, ...): ");
colNum = scanner.nextInt();
rowIndex = rowChar - 'A';
colIndex = colNum - 1;
cancelReservation(rowIndex, colIndex);
break;
case 4:
System.out.print("Berapa tempat duduk berurutan yang dicari? ");
int consecutive = scanner.nextInt();
findConsecutiveSeats(consecutive);
break;
case 5:
System.out.print("Berapa tempat duduk yang ingin di-reserve otomatis? ");
int autoReserve = scanner.nextInt();
autoReserveBestSeats(autoReserve);
break;
case 6:
displayRowStatistics();
break;
case 0:
System.out.println("Terima kasih telah menggunakan sistem reservasi!");
break;
default:
System.out.println("Pilihan tidak valid!");
}
} while (choice != 0);
scanner.close();
}
}
Analisis Performa dan Memory
Operasi | Time Complexity | Space Complexity | Keterangan |
---|---|---|---|
Array Creation | O(mĆn) | O(mĆn) | m=rows, n=columns |
Element Access | O(1) | O(1) | Direct indexing |
Linear Search | O(mĆn) | O(1) | Worst case: check all elements |
Matrix Multiplication | O(mĆnĆp) | O(mĆp) | A(mĆn) Ć B(nĆp) |
Transpose | O(mĆn) | O(mĆn) | New array needed |
š¾ Memory Management Tips
- Jagged Arrays: Gunakan untuk menghemat memory jika baris memiliki panjang berbeda
- Primitive vs Object: int[][] lebih efisien daripada Integer[][]
- Large Arrays: Pertimbangkan streaming atau chunking untuk data besar
- Garbage Collection: Set reference ke null setelah selesai digunakan
Best Practices Array 2D Java
ā Do’s (Yang Harus Dilakukan)
- Selalu validasi bounds sebelum akses array
- Gunakan enhanced for loop jika tidak butuh index
- Inisialisasi array dengan nilai default yang sesuai
- Dokumentasikan dimensi array dengan jelas
- Pertimbangkan menggunakan ArrayList untuk dynamic sizing
ā Don’ts (Yang Harus Dihindari)
- Jangan asumsikan semua baris memiliki panjang sama
- Hindari hardcode array dimensions dalam loop
- Jangan lupakan null checking untuk jagged arrays
- Hindari nested loops yang tidak perlu
- Jangan buat array yang terlalu besar tanpa pertimbangan memory
Common Pitfalls dan Solusinya
ā ļø ArrayIndexOutOfBoundsException
Masalah: Akses index di luar batas array
Solusi: Selalu cek bounds dengan kondisi i < array.length dan j < array[i].length
ā ļø NullPointerException
Masalah: Akses array yang belum diinisialisasi
Solusi: Pastikan array sudah di-instantiate dengan new sebelum digunakan
ā ļø Memory Overflow
Masalah: Array terlalu besar menyebabkan OutOfMemoryError
Solusi: Gunakan streaming, chunking, atau struktur data alternatif
Frequently Asked Questions (FAQ)
Apa perbedaan antara int[][] dan int[][]?
Keduanya sama dalam deklarasi. Yang berbeda adalah cara inisialisasi: int[][] arr = new int[3][4] membuat array rectangular, sedangkan int[][] arr = new int[3][] memungkinkan jagged array dimana setiap baris bisa memiliki panjang berbeda.
Bagaimana cara mengcopy array 2D dengan benar?
Untuk deep copy, gunakan loop nested atau Arrays.copyOf() untuk setiap baris. Hindari assignment langsung (arr2 = arr1) karena hanya copy reference. Contoh: for(int i=0; i<arr.length; i++) newArr[i] = Arrays.copyOf(arr[i], arr[i].length);
Kapan sebaiknya menggunakan ArrayList<ArrayList> instead of int[][]?
Gunakan ArrayList ketika: 1) Ukuran array tidak diketahui di awal, 2) Sering melakukan insert/delete, 3) Butuh dynamic resizing. Gunakan array 2D ketika: 1) Ukuran fixed, 2) Performance critical, 3) Memory usage penting.
Bagaimana cara mengoptimalkan performa operasi matrix besar?
Beberapa teknik: 1) Cache-friendly access patterns (akses row-wise), 2) Parallel processing dengan streams, 3) Blocking/tiling untuk matrix multiplication, 4) Gunakan library optimized seperti EJML, 5) Consider sparse matrix representations untuk data jarang.
Apakah ada batasan ukuran array 2D di Java?
Ya, batasan teoretis adalah Integer.MAX_VALUE (2^31 – 1) untuk total elemen, tapi praktisnya dibatasi heap memory. Untuk array besar, pertimbangkan: 1) Increase heap size (-Xmx), 2) Gunakan memory mapping, 3) Streaming processing, 4) External sorting algorithms.
Kesimpulan
Array 2 dimensi adalah struktur data fundamental yang sangat powerful dalam Java. Dari contoh-contoh program di atas, kita dapat melihat betapa versatile-nya array 2D dalam berbagai aplikasi mulai dari operasi matematika, game development, image processing, hingga sistem reservasi.
Kunci sukses dalam menggunakan array 2D adalah memahami konsep indexing, memory management, dan memilih algoritma yang tepat sesuai kebutuhan. Dengan latihan yang konsisten, Anda akan semakin mahir dalam memanfaatkan array 2D untuk menyelesaikan berbagai masalah pemrograman.