Vòng lặp for ba phần cổ điển
Vòng lặp (loop) for lặp lại một khối lệnh với số lần được kiểm soát. Dạng của Java gói ba thứ trong ngoặc tròn, ngăn cách bởi dấu chấm phẩy:
Ba phần này chạy theo một nhịp cố định:
- Khởi tạo (
int i = 0): chạy một lần, trước mọi thứ khác. - Điều kiện (
i < 5): được kiểm tra trước mỗi lần lặp; vòng lặp dừng khi điều kiện sai. - Cập nhật (
i++): chạy sau mỗi lần lặp, trước khi kiểm tra lại điều kiện.
Vì vậy đoạn code này in từ i = 0 đến i = 4. Biến đếm i chỉ tồn tại trong phạm vi vòng lặp: sau dấu ngoặc nhọn đóng, nó không còn nữa.
Đếm lên, đếm xuống và đếm theo bước
Ba phần này cho bạn toàn quyền điều khiển biến đếm:
i-- giảm đi một, i += 5 nhảy theo bước năm: cả hai đều là toán tử số học tính toán biến đếm. Điều kiện quyết định điểm dừng theo chiều đếm: dùng > khi đếm xuống, < hoặc <= khi đếm lên.
Duyệt một mảng
Vòng lặp có biến đếm rất hợp với mảng, dùng .length làm giới hạn và i làm chỉ số:
Lưu ý colors.length là thuộc tính, không có ngoặc tròn: mảng đặc biệt ở chỗ đó. List thì dùng list.size(). Điều kiện i < colors.length là đúng: chỉ số chạy từ 0 đến length - 1, nên dùng < (không phải <=) giúp tránh lỗi truy cập ngoài phạm vi.
Vòng lặp for-each nâng cao
Khi bạn chỉ cần từng phần tử mà không bao giờ cần chỉ số, for nâng cao gọn hơn và khó sai hơn: không có biến đếm nên không có lỗi lệch một đơn vị:
Hãy đọc for (String color : colors) là "với mỗi color trong colors". Nó dùng được với mảng và mọi thứ có thể duyệt. Đánh đổi là: bạn không có chỉ số, và không thể thêm hoặc xóa phần tử của collection trong lúc lặp (làm vậy sẽ ném một ngoại lệ lúc chạy, ConcurrentModificationException). Hãy dùng vòng lặp có biến đếm khi bạn cần một trong hai điều đó.
Vòng lặp lồng nhau
Một vòng lặp bên trong một vòng lặp khác, hữu ích cho lưới, bảng và việc ghép cặp. Vòng lặp bên trong chạy trọn vẹn cho mỗi lần lặp của vòng lặp bên ngoài:
Đoạn code này in ra bảng cửu chương 3x3. Khi lồng nhau sâu, hãy đặt tên biến đếm có nghĩa (row, col) thay vì i, j: bạn sẽ không bị nhầm biến nào là biến nào.
break và continue
break thoát khỏi vòng lặp ngay lập tức. continue bỏ qua phần còn lại của lần lặp hiện tại và nhảy tới bước cập nhật:
Đoạn code này in ra 1 3 5 7. continue bỏ qua các số chẵn; break kết thúc vòng lặp khi i sắp vượt quá 7. Trong vòng lặp lồng nhau, cả hai chỉ tác động lên vòng lặp trong cùng, trừ khi bạn dùng break có nhãn (labeled break).
Cẩn thận với vòng lặp vô hạn
Nếu điều kiện không bao giờ sai, vòng lặp chạy mãi mãi. Nguyên nhân thường gặp là quên bước cập nhật hoặc thay đổi biến đếm sai chiều:
for (int i = 0; i < 5; i--) { // i only ever decreases -> never reaches 5
System.out.println(i);
}
Một vòng lặp vô hạn có chủ đích bỏ trống cả ba phần, for (;;) { ... }, và dựa vào một break bên trong để dừng. Hãy dùng cách này hạn chế; while (true) thường dễ đọc hơn.
Tiếp theo: vòng lặp while
Vòng lặp for phát huy tác dụng khi bạn biết trước biến đếm. Khi bạn muốn lặp cho đến khi một điều kiện nào đó thay đổi, và không có biến đếm rõ ràng, vòng lặp while phù hợp hơn. Đó là nội dung trang tiếp theo.
Câu hỏi thường gặp
Cú pháp vòng lặp for trong Java là gì?
Vòng lặp for trong Java có ba phần trong ngoặc tròn, ngăn cách bởi dấu chấm phẩy: for (initialization; condition; update) { ... }. Ví dụ for (int i = 0; i < 5; i++) { ... } cho i bắt đầu từ 0, chạy thân vòng lặp khi i < 5, và cộng 1 vào i sau mỗi lần lặp. Cả ba phần đều không bắt buộc.
Vòng lặp for và foreach trong Java khác nhau thế nào?
Vòng lặp for cổ điển dùng biến đếm tường minh, nên bạn điều khiển được chỉ số và chiều duyệt, phù hợp nhất khi cần chỉ số hoặc muốn bỏ qua phần tử. Vòng lặp for-each nâng cao, for (Type item : collection), đi qua mọi phần tử theo thứ tự mà không cần chỉ số, gọn hơn khi bạn chỉ cần từng phần tử chứ không cần vị trí. for-each không thể thay đổi cấu trúc của collection trong lúc lặp.
Làm sao duyệt một mảng trong Java?
Hoặc truy cập theo chỉ số bằng vòng lặp có biến đếm, for (int i = 0; i < arr.length; i++) { use arr[i]; }, hoặc khi không cần chỉ số thì dùng for-each: for (int x : arr) { use x; }. Mảng cho biết kích thước qua thuộc tính .length (không có ngoặc), còn list dùng .size().