Bài 5: Xử lý mảng một chiều và vòng lặp cải tiến For-each

5.1. Khởi tạo, cấp phát bộ nhớ và truy xuất phần tử mảng qua chỉ số (Index)

5.5.1. Khái niệm và đặc điểm của mảng trong Java

  • Mảng là một tập hợp các biến có cùng kiểu dữ liệu, được lưu trữ tại các ô nhớ liền kề nhau trong bộ nhớ RAM.

  • Trong Java, mảng bản chất là một đối tượng (Object), do đó mảng được cấp phát trên vùng nhớ Heap.

  • Các phần tử trong mảng được định danh và truy xuất thông qua chỉ số (Index):

    • Chỉ số bắt đầu từ số 0 đến chiều_dài_mảng - 1.

    • Thuộc tính .length trả về tổng số phần tử (kích thước) của mảng.

2. Cú pháp khai báo và khởi tạo mảng

Có hai cách khởi tạo mảng chính:

  • Cách 1: Khai báo và cấp phát kích thước trước (chưa gán giá trị cụ thể):

    KieuDuLieu[] tenMang = new KieuDuLieu[so_luong_phan_tu];
    

    Ví dụ:

    int[] diem = new int[5]; // Tạo mảng gồm 5 phần tử: diem[0] đến diem[4]
    

    (Khi khởi tạo theo cách này, Java tự động gán giá trị mặc định: kiểu số là 0, kiểu số thực là 0.0, kiểu boolean là false, kiểu đối tượng là null).

  • Cách 2: Khởi tạo trực tiếp cùng danh sách giá trị ban đầu:

    KieuDuLieu[] tenMang = {gia_tri_0, gia_tri_1, ..., gia_tri_n};
    

    Ví dụ:

    int[] arr = {15, 24, 33, 40, 55, 60, 72};

3. Truy xuất và gán giá trị qua chỉ số Index

  • Đọc giá trị: tenMang[chiSo]

  • Gán giá trị mới: tenMang[chiSo] = giaTriMoi;

Chỉ số (Index)arr[0]arr[1]arr[2]arr[3]arr[4]arr[5]arr[6]
Giá trị (Value)15243340556072

5.2. Duyệt mảng bằng vòng lặp cải tiến For-each (Enhanced For Loop)

5.2.1. Cú pháp và nguyên lý vận hành

Vòng lặp for-each (được giới thiệu từ Java 5) chuyên dùng để duyệt tuần tự qua toàn bộ phần tử của mảng hoặc tập hợp:

for (KieuDuLieu bienLap : tenMang) {
    // Khối lệnh xử lý biếnLap
}
  • Nguyên lý: Mỗi chu kỳ lặp, Java tự động sao chép giá trị của phần tử tiếp theo trong tenMang và gán vào bienLap, sau đó thực thi khối lệnh. Quá trình tự động dừng khi duyệt hết phần tử cuối cùng.

2. So sánh vòng lặp For truyền thống và vòng lặp For-each

Tiêu chíVòng lặp For truyền thốngVòng lặp For-each (Cải tiến)
Cú phápfor (int i = 0; i < arr.length; i++)for (int x : arr)
Biến chỉ số iCó quản lý chỉ số index i.Hoàn toàn ẩn chỉ số index.
Nguy cơ lỗi tràn mảngDễ gặp lỗi nếu viết i <= arr.length.Không thể phát sinh lỗi tràn mảng.
Sửa đổi mảngCó thể ghi đè giá trị: arr[i] = 100;.Chỉ đọc (Read-only); gán x = 100; không làm thay đổi mảng gốc.
Mục đích phù hợpTìm vị trí index, đảo mảng, duyệt một phần mảng.Tính tổng, đếm số lượng, duyệt hiển thị toàn bộ mảng.

5.3. Các thuật toán cơ bản trên mảng một chiều

5.3.1. Thuật toán tính tổng và đếm phần tử thỏa điều kiện
  • Nguyên lý:

    1. Khởi tạo biến tích lũy tong = 0 và biến đếm dem = 0 ở ngoài vòng lặp.

    2. Dùng for-each duyệt qua từng phần tử x.

    3. Đặt điều kiện if kiểm tra (ví dụ: x % 5 == 0).

    4. Nếu đúng: cộng dồn vào tổng (tong += x;) và tăng biến đếm (dem++;).

5.3.2. Thuật toán tìm giá trị lớn nhất (Max) và nhỏ nhất (Min)

  • Kỹ thuật “Đặt lính canh”:

    1. Luôn gán giá trị ban đầu: int max = arr[0]; và int min = arr[0]; (không nên gán bằng 0 vì mảng có thể toàn số âm).

    2. Duyệt qua mảng:

      • Nếu x > max thì cập nhật: max = x;.

      • Nếu x < min thì cập nhật: min = x;.

5.3.3. Bảng mô phỏng từng bước (Trace Table) minh họa tính tổng số chia hết cho 5

Với mảng: arr = {15, 24, 33, 40, 55, 60, 72}

 
Vòng lặpPhần tử lấy ra (x)Điều kiện x % 5 == 0Xử lýBiến đếm (dem)Biến tổng (tong)
Khởi tạo———00
11515 (mod 5) == 0 (Đúng)dem++, tong += 15115
22424 (mod 5) == 4 (Sai)Bỏ qua115
33333 (mod 5) == 3 (Sai)Bỏ qua115
44040 (mod 5) == 0 (Đúng)dem++, tong += 40255
55555 (mod 5) == 0 (Đúng)dem++, tong += 553110
66060(mod 5) == 0 (Đúng)dem++, tong += 604170
77272 (mod 5) == 2 (Sai)Bỏ qua4170

Bài tập 5.1: Duyệt mảng, tính tổng và đếm phần tử bằngfor-each.

Giải thích

Viết chương trình khởi tạo mảng tĩnh gồm 7 phần tử số nguyên: int[] arr = {15, 24, 33, 40, 55, 60, 72}. Dùng vòng lặp for-each để lọc ra các phần tử chia hết cho 5, tính tổng các phần tử đó và đếm số lượng phần tử tìm thấy.

Bài tập 5.2: Tìm giá trị lớn nhất (Max) và nhỏ nhất (Min) kèm vị trí index

Viết chương trình nhập mảng gồm N số nguyên từ bàn phím. Tìm giá trị lớn nhất (Max) và giá trị nhỏ nhất (Min), xuất giá trị cực trị kèm các vị trí chỉ số index tương ứng.