Chuyển tới nội dung chính

🔁 Lặp Sau Kiểm Tra - Do-While Loops

Chào mừng đến với bài học về Do-While Loops - lặp ít nhất 1 lần trong Café Âu!

🎯 Món Ăn Hôm Nay

Tưởng tượng bạn là barista trong quán café:

  • Hỏi khách muốn gì → Luôn hỏi ít nhất 1 lần
  • Kiểm tra chất lượng ly đầu tiên → Pha xong mới biết ngon hay không
  • Chào khách vào cửa → Luôn chào dù có 0 hay nhiều khách

Đó chính là Do-While Loop - làm trước, kiểm tra sau!

☕ Do-While Loop Là Gì?

Do-While Loop = Làm trước rồi mới kiểm tra (chắc chắn làm ít nhất 1 lần)

// Hỏi khách ít nhất 1 lần
do {
System.out.println("☕ Quý khách muốn gọi món gì?");
// Nhận order từ khách
} while (conKhach);

Cấu trúc:

do {
// Công việc (luôn chạy ít nhất 1 lần)
} while (điều_kiện);

Ẩn Dụ Café:

  • do {...} = Làm việc trước
  • while (điều_kiện) = Sau đó mới kiểm tra
  • Khác while: While kiểm tra trước, do-while kiểm tra sau
  • Ứng dụng: Menu, nhập liệu, hỏi khách

👨‍🍳 Câu Chuyện Trong Quán

Sáng nay, barista cần phục vụ khách theo quy trình mới:

Tình huống 1: Hỏi khách gọi món (luôn hỏi ít nhất 1 lần)

Scanner scanner = new Scanner(System.in);
String monGoi;

do {
System.out.print("☕ Quý khách muốn gọi món gì? (hoặc 'không' để dừng): ");
monGoi = scanner.nextLine();

if (!monGoi.equals("không")) {
System.out.println("✅ Đã nhận: " + monGoi);
}
} while (!monGoi.equals("không"));

System.out.println("\n🙏 Cảm ơn quý khách!");

Tình huống 2: Kiểm tra chất lượng (ít nhất pha 1 ly)

int lyKiemTra = 0;
boolean chatLuongOK;

do {
lyKiemTra++;
System.out.println("☕ Pha ly thử số " + lyKiemTra + "...");

// Giả lập kiểm tra (ngẫu nhiên)
chatLuongOK = (Math.random() > 0.3);

if (chatLuongOK) {
System.out.println("✅ Chất lượng đạt!");
} else {
System.out.println("❌ Cần pha lại...");
}
} while (!chatLuongOK);

System.out.println("\n🎉 Đã có ly chuẩn sau " + lyKiemTra + " lần thử!");

🎉 Kết quả: Do-while đảm bảo làm ít nhất 1 lần dù điều kiện thế nào!

📝 Công Thức Nấu (Code Examples)

Ví Dụ 1: Do-While Cơ Bản

public class ChaoKhach {
public static void main(String[] args) {
int lanChao = 0;

System.out.println("🏪 Quán mở cửa!\n");

do {
lanChao++;
System.out.println("👋 Lần " + lanChao + ": Chào mừng quý khách!");
} while (lanChao < 3);

System.out.println("\n✅ Đã chào " + lanChao + " lần");
}
}

Output:

🏪 Quán mở cửa!

👋 Lần 1: Chào mừng quý khách!
👋 Lần 2: Chào mừng quý khách!
👋 Lần 3: Chào mừng quý khách!

✅ Đã chào 3 lần

Ví Dụ 2: Menu Tương Tác

import java.util.Scanner;

public class MenuCafe {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int chon;
int soLyDaBan = 0;

System.out.println("☕ CHÀO MỪNG ĐẾN QUÁN CAFÉ!\n");

do {
System.out.println("\n━━━━ MENU ━━━━");
System.out.println("1. Latte (50,000 VND)");
System.out.println("2. Cappuccino (45,000 VND)");
System.out.println("3. Espresso (40,000 VND)");
System.out.println("4. Xem thống kê");
System.out.println("0. Thanh toán & Thoát");
System.out.print("\nChọn (0-4): ");

chon = scanner.nextInt();

switch (chon) {
case 1:
System.out.println("✅ Đã gọi Latte");
soLyDaBan++;
break;
case 2:
System.out.println("✅ Đã gọi Cappuccino");
soLyDaBan++;
break;
case 3:
System.out.println("✅ Đã gọi Espresso");
soLyDaBan++;
break;
case 4:
System.out.println("📊 Tổng đã gọi: " + soLyDaBan + " ly");
break;
case 0:
System.out.println("\n🧾 HÓA ĐƠN:");
System.out.println("Tổng: " + soLyDaBan + " ly");
System.out.println("🙏 Cảm ơn quý khách!");
break;
default:
System.out.println("❌ Lựa chọn không hợp lệ!");
}
} while (chon != 0);

scanner.close();
}
}

Ví Dụ 3: Nhập Liệu Hợp Lệ

import java.util.Scanner;

public class NhapGiaHopLe {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int gia;

System.out.println("📝 CẬP NHẬT GIÁ LATTE\n");

do {
System.out.print("Nhập giá (20,000 - 100,000 VND): ");
gia = scanner.nextInt();

if (gia < 20000 || gia > 100000) {
System.out.println("❌ Giá không hợp lệ! Vui lòng nhập lại.\n");
}
} while (gia < 20000 || gia > 100000);

System.out.printf("\n✅ Đã cập nhật giá: %,d VND\n", gia);
scanner.close();
}
}

Output:

📝 CẬP NHẬT GIÁ LATTE

Nhập giá (20,000 - 100,000 VND): 150000
❌ Giá không hợp lệ! Vui lòng nhập lại.

Nhập giá (20,000 - 100,000 VND): 10000
❌ Giá không hợp lệ! Vui lòng nhập lại.

Nhập giá (20,000 - 100,000 VND): 50000

✅ Đã cập nhật giá: 50,000 VND

Ví Dụ 4: Xác Thực Mật Khẩu

import java.util.Scanner;

public class XacThucMatKhau {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String matKhau;
boolean hopLe;
int lanThu = 0;

System.out.println("🔒 TẠO MẬT KHẨU QUẢN LÝ\n");

do {
lanThu++;
System.out.print("Nhập mật khẩu (ít nhất 8 ký tự, có số): ");
matKhau = scanner.nextLine();

// Kiểm tra độ dài
boolean duDai = matKhau.length() >= 8;

// Kiểm tra có số
boolean coSo = matKhau.matches(".*\\d.*");

hopLe = duDai && coSo;

if (!hopLe) {
System.out.println("❌ Mật khẩu không đạt yêu cầu!");
if (!duDai) {
System.out.println(" → Cần ít nhất 8 ký tự");
}
if (!coSo) {
System.out.println(" → Cần có ít nhất 1 số");
}
System.out.println();
}
} while (!hopLe);

System.out.println("\n✅ Mật khẩu hợp lệ sau " + lanThu + " lần thử!");
scanner.close();
}
}

Ví Dụ 5: Đếm Ngược Giờ Mở Cửa

public class DemNguocMoCua {
public static void main(String[] args) throws InterruptedException {
int gioDemNguoc = 3;

System.out.println("⏰ CHUẨN BỊ MỞ CỬA!\n");

do {
System.out.println("⏱️ Còn " + gioDemNguoc + " giây...");
Thread.sleep(1000); // Đợi 1 giây
gioDemNguoc--;
} while (gioDemNguoc > 0);

System.out.println("\n🎉 QUÁN ĐÃ MỞ CỬA!");
}
}

Output:

⏰ CHUẨN BỊ MỞ CỬA!

⏱️ Còn 3 giây...
⏱️ Còn 2 giây...
⏱️ Còn 1 giây...

🎉 QUÁN ĐÃ MỞ CỬA!

🔥 Thực Hành Trong Quán

Bài Tập 1: Tính Tổng Tiền Đơn Hàng

import java.util.Scanner;

public class TinhTongTien {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int tongTien = 0;
int soMon = 0;
int gia;

System.out.println("💰 NHẬP ĐƠN HÀNG\n");

do {
System.out.print("Giá món thứ " + (soMon + 1) + " (0 để kết thúc): ");
gia = scanner.nextInt();

if (gia > 0) {
tongTien += gia;
soMon++;
System.out.printf(" → Tạm tính: %,d VND\n\n", tongTien);
}
} while (gia != 0);

System.out.println("━━━━━━━━━━━━━━━━━━━━━━");
System.out.printf("📊 Tổng: %d món - %,d VND\n", soMon, tongTien);

scanner.close();
}
}

Bài Tập 2: Trò Chơi Đoán Giá

import java.util.Scanner;

public class TroChoiDoanGia {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int giaDung = 45000; // Giá Cappuccino
int doan;
int lanDoan = 0;

System.out.println("🎮 TRÒ CHƠI: ĐOÁN GIÁ CAPPUCCINO!\n");

do {
lanDoan++;
System.out.print("Lần " + lanDoan + " - Đoán giá (VND): ");
doan = scanner.nextInt();

if (doan < giaDung) {
System.out.println("📈 Cao hơn!\n");
} else if (doan > giaDung) {
System.out.println("📉 Thấp hơn!\n");
}
} while (doan != giaDung);

System.out.println("\n🎉 CHÍNH XÁC!");
System.out.println("Bạn đoán đúng sau " + lanDoan + " lần!");

scanner.close();
}
}

Bài Tập 3: Tính Giai Thừa

public class TinhGiaiThua {
public static void main(String[] args) {
int n = 5; // Ví dụ: Combo 5 món
long giaiThua = 1;
int i = 1;

System.out.println("🧮 TÍNH SỐ CÁCH SẮP XẾP " + n + " MÓN:\n");

do {
System.out.printf("Bước %d: %d! = %d\n", i, i, giaiThua);
i++;
giaiThua *= i;
} while (i <= n);

System.out.println("\n✅ " + n + "! = " + giaiThua + " cách");
}
}

Output:

🧮 TÍNH SỐ CÁCH SẮP XẾP 5 MÓN:

Bước 1: 1! = 1
Bước 2: 2! = 2
Bước 3: 3! = 6
Bước 4: 4! = 24
Bước 5: 5! = 120

✅ 5! = 120 cách

Bài Tập 4: Tìm Số Chính Phương

public class TimSoChinhPhuong {
public static void main(String[] args) {
int n = 50; // Số ly
int i = 1;

System.out.println("🔢 SỐ CHÍNH PHƯƠNG ≤ " + n + ":\n");

do {
int binhPhuong = i * i;

if (binhPhuong <= n) {
System.out.printf("%d² = %d\n", i, binhPhuong);
}

i++;
} while (i * i <= n);

System.out.println("\n✅ Tìm được " + (i - 1) + " số chính phương");
}
}

⚠️ Những Lỗi Barista Thường Gặp

Lỗi 1: Nhầm Do-While Với While

// ❌ NHẦM: Dùng while (có thể không chạy lần nào)
int khach = 0;
while (khach > 0) { // Không chạy!
System.out.println("Chào khách");
khach--;
}

// ✅ ĐÚNG: Dùng do-while (chắc chắn chào ít nhất 1 lần)
int khach = 0;
do {
System.out.println("Chào khách"); // Chạy 1 lần
khach--;
} while (khach > 0);

Lỗi 2: Quên Cập Nhật Điều Kiện

// ❌ SAI: Vòng lặp vô hạn
int count = 0;
do {
System.out.println(count);
// Quên count++; → lặp vô hạn!
} while (count < 5);

// ✅ ĐÚNG: Cập nhật điều kiện
int count = 0;
do {
System.out.println(count);
count++; // Tăng count
} while (count < 5);

Lỗi 3: Điều Kiện Sai Logic

// ❌ SAI: Logic ngược
int gia = 0;
do {
System.out.print("Nhập giá: ");
// ... nhập gia
} while (gia >= 20000 && gia <= 100000); // Sai! Dừng khi ĐÚNG

// ✅ ĐÚNG: Logic đúng
int gia = 0;
do {
System.out.print("Nhập giá: ");
// ... nhập gia
} while (gia < 20000 || gia > 100000); // Lặp khi SAI

Lỗi 4: Thiếu Dấu Chấm Phẩy

// ❌ SAI: Thiếu dấu ; sau while
do {
System.out.println("Test");
} while (true) // Lỗi biên dịch!

// ✅ ĐÚNG: Có dấu ; sau while
do {
System.out.println("Test");
} while (true); // OK

💡 Bí Quyết Của Barista

  1. Dùng do-while khi chắc chắn làm ít nhất 1 lần: Menu, nhập liệu
  2. Kiểm tra logic điều kiện: Lặp khi SAI, dừng khi ĐÚNG
  3. Luôn có điều kiện dừng: Tránh vòng lặp vô hạn
  4. Nhớ dấu chấm phẩy: Sau while (điều_kiện);
  5. So sánh với while: While kiểm tra trước, do-while kiểm tra sau

🎓 Bạn Đã Học Được

  • ✅ Do-while = Làm trước, kiểm tra sau (ít nhất 1 lần)
  • ✅ do {...} while (điều_kiện); = Cấu trúc cơ bản
  • ✅ Khác while: While có thể không chạy lần nào
  • ✅ Ứng dụng: Menu, nhập liệu hợp lệ, xác thực
  • ✅ Nhớ dấu ; sau while (điều_kiện);

☕ Món Tiếp Theo

Đã biết cả 3 loại vòng lặp! Giờ học cách điều khiển vòng lặp:

👉 Điều Khiển Lặp - Break & Continue


💡 Lời Khuyên Cuối: Do-while giống chào khách vào cửa - luôn chào ít nhất 1 lần dù có khách hay không! Dùng khi cần đảm bảo thực hiện công việc trước khi kiểm tra điều kiện!