Mảng (Array) Trong Java

Trong phần này, chúng ta sẽ bắt đầu tìm hiểu về Mảng (Array) trong Java, một cấu trúc dữ liệu cho phép lưu trữ nhiều phần tử có cùng kiểu dữ liệu trong một biến duy nhất. Nội dung bao gồm: Mảng Một Chiều (One-Dimensional Array), Mảng Hai Chiều (2D array), Mảng Đa Chiều (multi-dimensional array).

Ⅰ. Mảng một chiều (One-Dimensional Array)

Mảng là một cấu trúc dữ liệu dùng để lưu trữ một số lượng cố định các phần tử có cùng kiểu dữ liệu. Kích thước của mảng được xác định khi tạo mảng và không thể thay đổi sau đó.

Phần tử và chỉ mục trong mảng

↳ Mỗi giá trị trong mảng được gọi là phần tử.

↳ Mỗi phần tử được truy cập bằng chỉ mục (index) bắt đầu từ 0.

↳ Ví dụ: phần tử thứ 9 sẽ được truy cập bằng chỉ mục 8.

Chỉ mục và phần tử trong mảng Java - minh họa
Ảnh mô tả chỉ mục và các phần tử trong một mảng.

Khai báo mảng một chiều

↳ Bạn có thể khai báo mảng trong Java bằng cách sử dụng cú pháp sau:

Cú pháp

kiểu_dữ_liệu[ ] tên_mảng;

Giải thích các thành phần:

↳ kiểu_dữ_liệu là kiểu dữ liệu của các phần tử được chứa;

↳ dấu ngoặc [ ] là các ký hiệu đặc biệt cho biết biến này chứa một mảng.

↳ tên_mảng có thể là bất kỳ tên nào bạn muốn, miễn là nó tuân theo các quy tắc và quy ước như đã thảo luận trước đó trong phần đặt tên.

Ví dụ

// Khai báo mảng số nguyên
int[ ] array;

Tương tự, bạn có thể khai báo các mảng kiểu khác:

Ví dụ

byte[ ] array;
short[ ] array;
long[ ] array;
float[ ] array;
double[ ] array;
boolean[ ] array;
char[ ] array;
String[ ] array;

Khởi tạo mảng một chiều

Bạn có thể khởi tạo mảng trong Java bạn có thể sử dụng một trong hai cách sau:

Cách 1: Sử dụng từ khóa new

Khởi tạo

kiểu_dữ_liệu[ ] tên_mảng = new kiểu_dữ_liệu[kích_thước];

Ví dụ

int[ ] numbers = new int[10]; // Khởi tạo mảng số nguyên với 10 phần tử
double[ ] prices = new double[5]; // Khởi tạo mảng số thực với 5 phần tử
String[ ] names = new String[3]; // Khởi tạo mảng chuỗi với 3 phần tử

Cách 2: Gán giá trị trực tiếp

Khởi tạo

kiểu_dữ_liệu[ ] tên_mảng = {giá_trị1, giá_trị2, ..., giá_trịN};

Ví dụ

int[ ] numbers = {10, 20, 30, 40, 50}; // Khởi tạo mảng số nguyên với giá trị
double[ ] prices = {1.5, 2.3, 4.2, 5.1}; // Khởi tạo mảng số thực với giá trị
String[ ] names = {"Vương", "Trường", "Dương"}; // Khởi tạo mảng chuỗi với giá trị

Ví dụ: Example.java

public class Example {
    public static void main(String[] args) {
        // khai báo một mảng số nguyên
        int[] anArray;

        // Khởi tạo mảng với kích thước 10
        anArray = new int[10];
           
        // khởi tạo phần tử đầu tiên
        anArray[0] = 10;
        // khởi tạo phần tử thứ hai
        anArray[1] = 20;
        // và khởi tạo các phần tử tiếp theo
        anArray[2] = 30;
        anArray[3] = 40;
        anArray[4] = 50;
        anArray[5] = 60;
        anArray[6] = 70;
        anArray[7] = 80;
        anArray[8] = 90;
        anArray[9] = 100;

        System.out.println("Phần tử tại mục 0: "+ anArray[0]);
        System.out.println("Phần tử tại mục 1: "+ anArray[1]);
        System.out.println("Phần tử tại mục 2: "+ anArray[2]);
        System.out.println("Phần tử tại mục 3: "+ anArray[3]);
        System.out.println("Phần tử tại mục 4: "+ anArray[4]);
        System.out.println("Phần tử tại mục 5: "+ anArray[5]);
        System.out.println("Phần tử tại mục 6: "+ anArray[6]);
        System.out.println("Phần tử tại mục 7: "+ anArray[7]);
        System.out.println("Phần tử tại mục 8: "+ anArray[8]);
        System.out.println("Phần tử tại mục 9: "+ anArray[9]);
    }
} 

Kết quả của chương trình là:

Phần tử tại mục 0: 10
Phần tử tại mục 1: 20
Phần tử tại mục 2: 30
Phần tử tại mục 3: 40
Phần tử tại mục 4: 50
Phần tử tại mục 5: 60
Phần tử tại mục 6: 70
Phần tử tại mục 7: 80
Phần tử tại mục 8: 90
Phần tử tại mục 9: 100

Trong tình huống lập trình trong thế giới thực, có thể bạn sẽ sử dụng một trong các cấu trúc vòng lặp được hỗ trợ để lặp qua từng phần tử của mảng, thay vì viết từng dòng riêng lẻ như trong ví dụ trên. Tuy nhiên, ví dụ trên minh họa rõ ràng giúp bạn hiểu hơn về cú pháp mảng.

Các phương thức thường gặp trong lớp Arrays của Java

Mặc dù mảng trong Java không phải là đối tượng theo nghĩa đầy đủ, nhưng bạn có thể sử dụng các phương thức từ lớp Arrays trong gói java.util để thao tác với dữ liệu trong mảng. Dưới đây là một số phương thức thông dụng:

1. Truy cập phần tử và thay đổi giá trị

↳ array[index]: Truy cập phần tử tại vị trí index trong mảng.

↳ array[index] = value: Gán giá trị value cho phần tử tại vị trí index.

↳ Arrays.fill(array, value): Điền giá trị value cho tất cả các phần tử trong mảng.

↳ length: sử dụng length để biết có bao nhiêu phần tử một mảng.

Dưới đây là một ví dụ về cách truy cập phần tử và thay đổi giá trị trong mảng trong java:

Ví dụ: Example.java

import java.util.Arrays;
public class Example {
    public static void main(String[] args) {
        // Khai báo và khởi tạo mảng
        int[] array = {1, 2, 3, 4, 5};

        // Truy cập và in ra phần tử tại vị trí index = 2
        System.out.println("Phần tử tại index 2: " + array[2]);

        // Thay đổi giá trị của phần tử tại vị trí index = 2 thành 10
        array[2] = 10;
        System.out.println("Mảng sau khi thay đổi giá trị tại index 2: " + Arrays.toString(array));

        // Điền giá trị 7 cho tất cả các phần tử trong mảng
        Arrays.fill(array, 7);
        System.out.println("Mảng sau khi điền giá trị 7: " + Arrays.toString(array));

        // sử dụng length biết có bao nhiêu phần tử một mảng
        System.out.println("Độ dài của mảng là: " + array.length);
    }
}

Kết quả của chương trình là:

Phần tử tại index 2: 3
Mảng sau khi thay đổi giá trị tại index 2: [1, 2, 10, 4, 5]
Mảng sau khi điền giá trị 7: [7, 7, 7, 7, 7]
Độ dài của mảng là: 5

2. Duyệt qua các phần tử của mảng trong Java

↳ Sử dụng vòng lặp for

Vòng lặp for là cách phổ biến nhất để duyệt qua các phần tử của mảng. Bạn có thể sử dụng biến chỉ mục để truy cập từng phần tử trong mảng.

Ví dụ: Example.java

public class Example {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5};

        // Duyệt qua các phần tử của mảng bằng vòng lặp for
        for (int i = 0; i < array.length; i++) {
            System.out.println("Phần tử tại index " + i + ": " + array[i]);
        }
    }
}

Kết quả của chương trình là:

Phần tử tại index 0: 1
Phần tử tại index 1: 2
Phần tử tại index 2: 3
Phần tử tại index 3: 4
Phần tử tại index 4: 5

↳ Sử dụng vòng lặp for-each

Vòng lặp for-each (hay còn gọi là enhanced for loop) được giới thiệu từ Java 5, giúp việc duyệt qua các phần tử của mảng trở nên dễ dàng hơn.

Ví dụ: Example.java

public class Example {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5};

        // Duyệt qua các phần tử của mảng bằng vòng lặp for-each
        for (int element : array) {
            System.out.println("Phần tử: " + element);
        }
    }
}

Kết quả của chương trình là:

Phần tử: 1
Phần tử: 2
Phần tử: 3
Phần tử: 4
Phần tử: 5

↳ Sử dụng vòng lặp while

Bạn cũng có thể sử dụng vòng lặp while để duyệt qua các phần tử của mảng. Đảm bảo rằng bạn có một biến chỉ mục và cập nhật nó trong vòng lặp.

Ví dụ: Example.java

public class Example {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5};
        int i = 0;

        // Duyệt qua các phần tử của mảng bằng vòng lặp while
        while (i < array.length) {
            System.out.println("Phần tử tại index " + i + ": " + array[i]);
            i++;
        }
    }
}

Kết quả của chương trình là:

Phần tử tại index 0: 1
Phần tử tại index 1: 2
Phần tử tại index 2: 3
Phần tử tại index 3: 4
Phần tử tại index 4: 5

↳ Sử dụng vòng lặp do-while

Vòng lặp do-while đảm bảo rằng khối lệnh bên trong sẽ được thực thi ít nhất một lần.

Ví dụ: Example.java

public class Example {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5};
        int i = 0;

        // Duyệt qua các phần tử của mảng bằng vòng lặp do-while
        do {
            System.out.println("Phần tử tại index " + i + ": " + array[i]);
            i++;
        } while (i < array.length);
    }
}

Kết quả của chương trình là:

Phần tử tại index 0: 1
Phần tử tại index 1: 2
Phần tử tại index 2: 3
Phần tử tại index 3: 4
Phần tử tại index 4: 5

3. Sắp xếp

↳ Arrays.sort(array): Sắp xếp các phần tử trong mảng theo thứ tự tăng dần.

Dưới đây là một ví dụ về cách sử dụng phương thức Arrays.sort(array) để sắp xếp một mảng số nguyên:

Ví dụ: Example.java

import java.util.Arrays;

public class Example {
    public static void main(String[] args) {
        // Sắp xếp mảng số nguyên theo thứ tự tăng dần
        int[] intArray = {5, 2, 8, 3, 9};
        System.out.println("Mảng int gốc: " + Arrays.toString(intArray));
        
        Arrays.sort(intArray);
        System.out.println("Mảng int đã được sắp xếp: " + Arrays.toString(intArray));
    }
}

Kết quả của chương trình là:

Mảng int gốc: [5, 2, 8, 3, 9]
Mảng int đã được sắp xếp: [2, 3, 5, 8, 9]

4. Tìm kiếm

↳ Arrays.binarySearch(array, value):Tìm kiếm giá trị value trong mảng đã được sắp xếp theo thứ tự. Trả về vị trí của phần tử nếu tìm thấy, hoặc điểm chèn dự kiến nếu không tìm thấy.

↳ Arrays.asList(array): Chuyển đổi mảng thành danh sách (implementing the List interface) để sử dụng các phương thức tìm kiếm của danh sách.

Dưới đây là ví dụ về cách sử dụng cả hai phương thức Arrays.binarySearch() và Arrays.asList() trong Java.

Ví dụ: Example.java

import java.util.Arrays;
import java.util.List;

public class Example {
    public static void main(String[] args) {
        // Khởi tạo và sắp xếp mảng số nguyên
        int[] intArray = {5, 2, 8, 3, 9};
        Arrays.sort(intArray); // Mảng cần được sắp xếp trước khi sử dụng binarySearch
        System.out.println("Mảng int đã được sắp xếp: " + Arrays.toString(intArray));

        // Sử dụng Arrays.binarySearch để tìm kiếm phần tử
        int key = 8;
        int index = Arrays.binarySearch(intArray, key);
        if (index >= 0) {
            System.out.println("Phần tử " + key + " đã được tìm thấy tại chỉ mục: " + index);
        } else {
            System.out.println("Phần tử " + key + " Không tìm thấy");
        }

        // Khởi tạo mảng chuỗi
        String[] strArray = {"Apple", "Orange", "Banana", "Grapes"};
        System.out.println("\nMảng String gốc: " + Arrays.toString(strArray));
        
        // Chuyển đổi mảng thành danh sách
        List<String> strList = Arrays.asList(strArray);
        System.out.println("đã chuyển đổi sang List: " + strList);

        // Sử dụng List.contains() để tìm kiếm phần tử
        String searchStr = "Banana";
        if (strList.contains(searchStr)) {
            System.out.println("Phần tử \\"" + searchStr + "\\" đã được tìm thấy trong list.");
        } else {
            System.out.println("Phần tử \\"" + searchStr + "\\" Không được tìm thấy list.");
        }
    }
}

Kết quả của chương trình là:

Mảng int đã được sắp xếp: [2, 3, 5, 8, 9]
Phần tử 8 đã được tìm thấy tại chỉ mục: 3

Mảng String gốc: [Apple, Orange, Banana, Grapes]
đã chuyển đổi sang List: [Apple, Orange, Banana, Grapes]
Phần tử "Banana" đã được tìm thấy trong list.

5. So sánh

↳ Arrays.equals(array1, array2): So sánh hai mảng xem có bằng nhau hay không. Trả về true nếu hai mảng bằng nhau, false nếu khác nhau.

Dưới đây là một ví dụ về việc sử dụng phương thức Arrays.equals() để so sánh hai mảng trong java:

Ví dụ: Example.java

import java.util.Arrays;
import java.util.Comparator;

public class Example {
    public static void main(String[] args) {
        // Khởi tạo hai mảng số nguyên
        int[] intArray1 = {5, 2, 8, 3, 9};
        int[] intArray2 = {5, 2, 8, 3, 9};
        
        // Sắp xếp mảng số nguyên theo thứ tự tăng dần
        Arrays.sort(intArray1);
        Arrays.sort(intArray2);
        
        // So sánh hai mảng số nguyên
        boolean areIntArraysEqual = Arrays.equals(intArray1, intArray2);
        System.out.println("Mảng số nguyên có bằng nhau không? " + areIntArraysEqual);

        // Khởi tạo hai mảng chuỗi
        String[] strArray1 = {"Apple", "Orange", "Banana", "Grapes"};
        String[] strArray2 = {"Apple", "Orange", "Banana"};
        
        // Sắp xếp mảng chuỗi theo thứ tự giảm dần
        Arrays.sort(strArray1, Comparator.reverseOrder());
        Arrays.sort(strArray2, Comparator.reverseOrder());
        
        // So sánh hai mảng chuỗi
        boolean areStrArraysEqual = Arrays.equals(strArray1, strArray2);
        System.out.println("Mảng chuỗi có bằng nhau không? " + areStrArraysEqual);
    }
}

Kết quả của chương trình là:

Mảng số nguyên có bằng nhau không? true
Mảng chuỗi có bằng nhau không? false

6. Sao chép

↳ Arrays.copyOf(array, length): Sao chép toàn bộ mảng thành một mảng mới có kích thước length.

↳ Arrays.copyOfRange(array, startIndex, endIndex): Sao chép một phần mảng từ startIndex đến endIndex - 1.

Dưới đây là một ví dụ về cách sử dụng hai phương thức Arrays.copyOf và Arrays.copyOfRange trong java:

Ví dụ: Example.java

import java.util.Arrays;

public class Example {
    public static void main(String[] args) {
        // Tạo mảng ban đầu
        int[] originalArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        System.out.println("Mảng gốc: " + Arrays.toString(originalArray));
        
        // Sao chép toàn bộ mảng với độ dài mới
        int[] copiedArray = Arrays.copyOf(originalArray, 15);
        System.out.println("Mảng được sao chép với độ dài mới: " + Arrays.toString(copiedArray));
        
        // Sao chép một phần của mảng từ vị trí 2 đến vị trí 5 (không bao gồm vị trí 5)
        int[] partialCopiedArray = Arrays.copyOfRange(originalArray, 2, 5);
        System.out.println("Mảng được sao chép một phần (chỉ số 2 đến 5): " + Arrays.toString(partialCopiedArray));
    }
}

Kết quả của chương trình là:

Mảng gốc: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Mảng được sao chép với độ dài mới: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0]
Mảng được sao chép một phần (chỉ số 2 đến 5): [3, 4, 5]

Xem tất cả phương thức của lớp java.util.Arrays:Tại đây

Ⅱ. Mảng Hai Chiều (2D array)

↳ Mảng hai chiều là mảng gồm nhiều mảng được sắp xếp theo hàng và cột.

↳ Hình dung như một bảng dữ liệu với nhiều hàng và cột.

↳ Mỗi phần tử được truy cập bằng hai chỉ mục: chỉ mục hàng và chỉ mục cột.

Cấu trúc khai báo mảng hai chiều

Cấu trúc

kiểu_dữ_liệu[ ][ ] tên_mảng = new kiểu_dữ_liệu[số_hàng][số_cột];

Ví dụ

int[ ][ ] matrix = new int[3][4]; // Mảng 3 hàng, 4 cột

Truy Cập Phần Tử

matrix[hàng][cột] = giá_trị;
giá_trị = matrix[hàng][cột];

Dưới đây là một ví dụ về mảng hai chiều trong java:

Ví dụ: Example.java

public class Example {
    public static void main(String[] args) {
        // Khai báo và khởi tạo mảng hai chiều
        int[][] twoArray = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };

        // Truy cập và in phần tử trong mảng hai chiều
        System.out.println("Phần tử tại hàng 1, cột 2: " + twoArray[1][1]);

        // Duyệt qua mảng hai chiều bằng vòng lặp for
        System.out.println("Duyệt qua mảng hai chiều:");
        for (int i = 0; i < twoArray.length; i++) {
            for (int j = 0; j < twoArray[i].length; j++) {
                System.out.print(twoArray[i][j] + " ");
            }
            System.out.println();
        }
    }
}

Kết quả của chương trình là:

Phần tử tại hàng 1, cột 2: 5
Duyệt qua mảng hai chiều:
1 2 3
4 5 6
7 8 9

Dưới đây là một ví dụ về cộng mảng hai chiều trong java

Ví dụ: Example.java

public class Example {
    public static void main(String[] args) {
        // Khởi tạo hai mảng hai chiều
        int[][] matrix1 = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };

        int[][] matrix2 = {
            {9, 8, 7},
            {6, 5, 4},
            {3, 2, 1}
        };

        // Kiểm tra xem hai ma trận có cùng kích thước không
        if (matrix1.length != matrix2.length || matrix1[0].length != matrix2[0].length) {
            System.out.println("Hai ma trận không cùng kích thước. Không thể cộng chúng.");
            return;
        }

        // Khởi tạo ma trận kết quả
        int[][] resultMatrix = new int[matrix1.length][matrix1[0].length];

        // Thực hiện phép cộng hai ma trận
        for (int i = 0; i < matrix1.length; i++) {
            for (int j = 0; j < matrix1[i].length; j++) {
                resultMatrix[i][j] = matrix1[i][j] + matrix2[i][j];
            }
        }

        // In ma trận kết quả
        System.out.println("Ma trận kết quả sau khi cộng:");
        for (int i = 0; i < resultMatrix.length; i++) {
            for (int j = 0; j < resultMatrix[i].length; j++) {
                System.out.print(resultMatrix[i][j] + " ");
            }
            System.out.println();
        }
    }
}

Kết quả của chương trình là:

Ma trận kết quả sau khi cộng:
10 10 10
10 10 10
10 10 10

Ⅲ. Mảng Đa Chiều (multi-dimensional array)

↳ Mảng đa chiều là mảng có hơn hai chiều (ví dụ: 3 chiều, 4 chiều, v.v.).

↳ Hình dung như một khối dữ liệu với nhiều chiều, mỗi chiều được biểu thị bằng một chỉ mục.

↳ Khai báo và truy cập phần tử tương tự như mảng hai chiều, nhưng với nhiều chỉ mục hơn.

Dưới đây là một ví dụ về mảng ba chiều trong java

Ví dụ: Example.java

public class Example {
    public static void main(String[] args) {
        // Khai báo và khởi tạo mảng ba chiều
        int[][][] threeArray = {
            {//khối thứ nhất là index 0
                {1, 2, 3},
                {4, 5, 6}
            },
            {//khối thứ hai là index 1
                {7, 8, 9},
                {10, 11, 12}
            }
        };

        // Truy cập và in phần tử trong mảng ba chiều
        System.out.println("Phần tử ở khối 1, hàng 2, cột 3: " + threeArray[0][1][2]);

        // Duyệt qua mảng ba chiều bằng vòng lặp for
        System.out.println("Duyệt qua mảng ba chiều:");
        for (int i = 0; i < threeArray.length; i++) {
            for (int j = 0; j < threeArray[i].length; j++) {
                for (int k = 0; k < threeArray[i][j].length; k++) {
                    System.out.print(threeArray[i][j][k] + " ");
                }
                System.out.println();
            }
            System.out.println();
        }
    }
}

Kết quả của chương trình là:

Phần tử ở khối 1, hàng 2, cột 3: 6
Duyệt qua mảng ba chiều:
1 2 3
4 5 6
7 8 9
10 11 12

Mảng hai chiều và đa chiều được sử dụng để lưu trữ dữ liệu dạng bảng, ví dụ:

↳ Ma trận toán học

↳ Hình ảnh bitmap

↳ Bảng dữ liệu

↳ Thuật toán ma trận

↳ Lựa chọn kiểu mảng phù hợp với cấu trúc dữ liệu và thao tác cần thực hiện.

So sánh mảng một chiều, hai chiều và đa chiều

Đặc điểmMảng Một ChiềuMảng Hai ChiềuMảng Đa Chiều
Số chiều12N (> 2)
Cấu trúcDãy các phần tửBảng dữ liệuKhối dữ liệu
Truy cậpChỉ mục đơnHai chỉ mục (hàng, cột)Nhiều chỉ mục (chiều 1, chiều 2, ...)
Ứng dụngLưu trữ dữ liệu dạng danh sáchLưu trữ dữ liệu dạng bảngLưu trữ dữ liệu dạng khối

Kết luận:

Mảng hai chiều và đa chiều là công cụ mạnh mẽ để lưu trữ và thao tác dữ liệu dạng bảng và khối trong Java. Hiểu rõ cách khai báo, truy cập và sử dụng các loại mảng này sẽ giúp bạn viết code linh hoạt và hiệu quả hơn cho các bài toán phức tạp.

Câu Nói Truyền Cảm Hứng

“Bắt đầu ở đâu không quan trọng, quan trọng là bạn sẵn sàng bắt đầu.” – W. Clement Stone

Không Gian Tích Cực

“Chúc bạn luôn giữ vững niềm tin và sức mạnh để vượt qua mọi thử thách trong cuộc sống.”