🔗 Kết Hợp Điều Kiện - Logical Operators
Chào mừng đến với bài học về Logical Operators - cách kết hợp nhiều điều kiện trong Café!
🎯 Món Ăn Hôm Nay
Tưởng tượng bạn đang kiểm tra điều kiện phục vụ:
- Có tiền VÀ có chỗ ngồi → Phục vụ được (AND)
- Thành viên VIP HOẶC có mã giảm giá → Được giảm giá (OR)
- KHÔNG phải giờ nghỉ → Mở cửa (NOT)
Đó chính là Logical Operators - kết hợp nhiều điều kiện!
🔗 Logical Operators Là Gì?
Logical Operators = Kết nối điều kiện (kết hợp nhiều boolean)
Có 3 toán tử chính:
boolean coTien = true;
boolean coChoNgoi = true;
// AND - Cả 2 đều đúng
boolean phucVuDuoc = coTien && coChoNgoi; // true
// OR - 1 trong 2 đúng
boolean duocGiamGia = isVIP || coMaGiamGia; // true nếu 1 trong 2 đúng
// NOT - Đảo ngược
boolean dongCua = !moC ua; // true nếu đóng cửa
☕ Ẩn Dụ Café:
- && (AND) = Cả 2 điều kiện đều cần
- || (OR) = 1 trong 2 điều kiện đủ
- ! (NOT) = Phủ định, đảo ngược
- Kết hợp = Ra quyết định phức tạp
📊 Bảng 3 Toán Tử Logic
| Toán Tử | Tên | Ví Dụ Café | Kết Quả |
|---|---|---|---|
&& | AND (VÀ) | coTien && coChoNgoi | Cả 2 đều true |
|| | OR (HOẶC) | isVIP || coMa | 1 trong 2 true |
! | NOT (KHÔNG) | !hetHang | Đảo ngược boolean |
Truth Table - Bảng Chân Lý
AND (&&)
| A | B | A && B |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
OR (||)
| A | B | A || B |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
NOT (!)
| A | !A |
|---|---|
| true | false |
| false | true |
👨🍳 Câu Chuyện Trong Quán
Tình huống 1: Kiểm Tra Điều Kiện Phục Vụ (AND)
public class DieuKienPhucVu {
public static void main(String[] args) {
boolean coTien = true;
boolean coChoNgoi = true;
boolean trongGioMoCua = true;
// Cần cả 3 điều kiện
if (coTien && coChoNgoi && trongGioMoCua) {
System.out.println("✅ Phục vụ được!");
} else {
System.out.println("❌ Không thể phục vụ:");
if (!coTien) System.out.println(" - Khách không có tiền");
if (!coChoNgoi) System.out.println(" - Hết chỗ ngồi");
if (!trongGioMoCua) System.out.println(" - Ngoài giờ mở cửa");
}
}
}
Tình huống 2: Ưu Đãi Khách Hàng (OR)
public class UuDaiKhach {
public static void main(String[] args) {
boolean laThanhVienVIP = false;
boolean coMaGiamGia = true;
boolean laSinhNhat = false;
// Chỉ cần 1 trong 3 điều kiện
if (laThanhVienVIP || coMaGiamGia || laSinhNhat) {
System.out.println("🎉 Được giảm giá!");
if (laThanhVienVIP) System.out.println(" → VIP: -20%");
if (coMaGiamGia) System.out.println(" → Mã giảm giá: -15%");
if (laSinhNhat) System.out.println(" → Sinh nhật: -10%");
} else {
System.out.println("💰 Giá gốc");
}
}
}
📝 Công Thức Nấu (Code Examples)
Ví Dụ 1: AND (&&) - Kiểm Tra Đầy Đủ
public class KiemTraDayDu {
public static void main(String[] args) {
int tuoi = 20;
int tienTrongTui = 60000;
int giaDoUong = 50000;
boolean coGiayTo = true;
System.out.println("🔍 KIỂM TRA ĐIỀU KIỆN:\n");
// Cần tất cả điều kiện
if (tuoi >= 18 && tienTrongTui >= giaDoUong && coGiayTo) {
System.out.println("✅ Đủ điều kiện mua đồ uống!");
System.out.println("Tuổi: " + tuoi + " (>= 18) ✓");
System.out.println("Tiền: " + tienTrongTui + " (>= " + giaDoUong + ") ✓");
System.out.println("Giấy tờ: Có ✓");
} else {
System.out.println("❌ Không đủ điều kiện:");
if (tuoi < 18) System.out.println(" - Chưa đủ 18 tuổi");
if (tienTrongTui < giaDoUong) System.out.println(" - Không đủ tiền");
if (!coGiayTo) System.out.println(" - Thiếu giấy tờ");
}
}
}
Ví Dụ 2: OR (||) - Chấp Nhận Thanh Toán
public class PhuongThucThanhToan {
public static void main(String[] args) {
boolean coTienMat = false;
boolean coThe = true;
boolean coViDienTu = false;
System.out.println("💳 PHƯƠNG THỨC THANH TOÁN:\n");
// Chỉ cần 1 phương thức
if (coTienMat || coThe || coViDienTu) {
System.out.println("✅ Có thể thanh toán!");
if (coTienMat) System.out.println("→ Tiền mặt");
if (coThe) System.out.println("→ Thẻ ngân hàng");
if (coViDienTu) System.out.println("→ Ví điện tử");
} else {
System.out.println("❌ Không có phương thức thanh toán!");
}
}
}
Ví Dụ 3: NOT (!) - Đảo Ngược Điều Kiện
public class TrangThaiQuan {
public static void main(String[] args) {
boolean hetNguyenLieu = false;
boolean hetChoNgoi = false;
boolean dangBaoTri = false;
System.out.println("🏪 TRẠNG THÁI QUÁN:\n");
// Kiểm tra phủ định
if (!hetNguyenLieu && !hetChoNgoi && !dangBaoTri) {
System.out.println("✅ Quán đang hoạt động bình thường!");
} else {
System.out.println("⚠️ Quán gặp vấn đề:");
if (hetNguyenLieu) System.out.println(" - Hết nguyên liệu");
if (hetChoNgoi) System.out.println(" - Hết chỗ ngồi");
if (dangBaoTri) System.out.println(" - Đang bảo trì");
}
// Dùng ! để đảo
boolean coThePhucVu = !hetNguyenLieu && !dangBaoTri;
System.out.println("\nCó thể phục vụ: " + coThePhucVu);
}
}
Ví Dụ 4: Kết Hợp AND & OR
public class GioMoCua {
public static void main(String[] args) {
int gio = 19; // 7h tối
boolean laChuNhat = false;
System.out.println("⏰ GIỜ: " + gio + ":00");
System.out.println("📅 Chủ nhật: " + (laChuNhat ? "Có" : "Không") + "\n");
// Giờ mở cửa: 7h-22h (T2-T6), 8h-23h (T7-CN)
boolean moC uaThuong = (gio >= 7 && gio < 22) && !laChuNhat;
boolean moCuaCuoiTuan = (gio >= 8 && gio < 23) && laChuNhat;
if (moC uaThuong || moCuaCuoiTuan) {
System.out.println("✅ Quán đang mở cửa!");
} else {
System.out.println("🔒 Quán đã đóng cửa!");
}
}
}
Ví Dụ 5: Short-Circuit Evaluation
public class ShortCircuit {
public static void main(String[] args) {
int soLuongKho = 0;
int soLuongDat = 5;
System.out.println("📦 KIỂM TRA KHO:\n");
// Short-circuit với &&
// Nếu soLuongKho > 0 là false, không kiểm tra điều kiện sau
if (soLuongKho > 0 && soLuongKho >= soLuongDat) {
System.out.println("✅ Đủ hàng giao!");
} else {
System.out.println("❌ Không đủ hàng!");
}
// Short-circuit với ||
boolean laVIP = true;
boolean coMa = false;
// Nếu laVIP là true, không kiểm tra coMa
if (laVIP || coMa) {
System.out.println("\n🎁 Được giảm giá!");
}
// Tránh lỗi với short-circuit
String tenKhach = null;
if (tenKhach != null && tenKhach.length() > 0) {
// An toàn: tenKhach != null được check trước
System.out.println("Tên: " + tenKhach);
}
}
}
🔥 Thực Hành Trong Quán
Bài Tập 1: Kiểm Tra Tài Khoản VIP
public class TaiKhoanVIP {
public static void main(String[] args) {
int soLanMua = 25;
int tongChiTieu = 1500000;
boolean dangKyThanhVien = true;
System.out.println("👤 KIỂM TRA TÀI KHOẢN VIP:\n");
System.out.println("Số lần mua: " + soLanMua);
System.out.println("Tổng chi tiêu: " + tongChiTieu + " VND");
System.out.println("Đã đăng ký: " + (dangKyThanhVien ? "Có" : "Không"));
System.out.println();
// Điều kiện VIP: (>= 20 lần MUA HOẶC >= 1 triệu) VÀ đã đăng ký
if ((soLanMua >= 20 || tongChiTieu >= 1000000) && dangKyThanhVien) {
System.out.println("🌟 Chúc mừng! Bạn là VIP!");
System.out.println("Ưu đãi:");
System.out.println(" - Giảm 20% mọi đơn hàng");
System.out.println(" - Miễn phí ship");
System.out.println(" - Tích điểm x2");
} else {
System.out.println("💳 Tài khoản thường");
if (!dangKyThanhVien) {
System.out.println("⚠️ Cần đăng ký để trở thành VIP!");
}
}
}
}
Bài Tập 2: Hệ Thống Đặt Bàn
public class DatBan {
public static void main(String[] args) {
int soKhach = 6;
int gio = 18; // 6h chiều
boolean coDatTruoc = true;
int soBanTrong = 2;
System.out.println("🪑 KIỂM TRA ĐẶT BÀN:\n");
System.out.println("Số khách: " + soKhach);
System.out.println("Giờ: " + gio + ":00");
System.out.println("Đặt trước: " + (coDatTruoc ? "Có" : "Không"));
System.out.println("Bàn trống: " + soBanTrong);
System.out.println();
// Giờ cao điểm: 11h-14h HOẶC 17h-20h
boolean gioCaoDiem = (gio >= 11 && gio < 14) || (gio >= 17 && gio < 20);
// Chấp nhận: Có bàn trống VÀ (KHÔNG cao điểm HOẶC đã đặt trước)
if (soBanTrong > 0 && (!gioCaoDiem || coDatTruoc)) {
System.out.println("✅ Chấp nhận đặt bàn!");
if (gioCaoDiem) {
System.out.println("⚡ Giờ cao điểm - May mắn đã đặt trước!");
}
} else {
System.out.println("❌ Không thể đặt bàn:");
if (soBanTrong == 0) {
System.out.println(" - Hết bàn trống");
}
if (gioCaoDiem && !coDatTruoc) {
System.out.println(" - Giờ cao điểm cần đặt trước");
}
}
}
}
Bài Tập 3: Xác Thực Đơn Hàng
public class XacThucDonHang {
public static void main(String[] args) {
String tenKhach = "Anh Minh";
String soDienThoai = "0123456789";
String diaChi = "123 Lê Lợi";
int tongTien = 200000;
boolean dongYDieuKhoan = true;
System.out.println("📋 XÁC THỰC ĐƠN HÀNG:\n");
// Kiểm tra thông tin bắt buộc
boolean coTen = tenKhach != null && !tenKhach.isEmpty();
boolean coSDT = soDienThoai != null && soDienThoai.length() == 10;
boolean coDiaChi = diaChi != null && !diaChi.isEmpty();
boolean hopLe = tongTien > 0 && dongYDieuKhoan;
if (coTen && coSDT && coDiaChi && hopLe) {
System.out.println("✅ Đơn hàng hợp lệ!");
System.out.println("\nTHÔNG TIN:");
System.out.println("Tên: " + tenKhach);
System.out.println("SĐT: " + soDienThoai);
System.out.println("Địa chỉ: " + diaChi);
System.out.println("Tổng: " + tongTien + " VND");
} else {
System.out.println("❌ Đơn hàng không hợp lệ:");
if (!coTen) System.out.println(" - Thiếu tên khách");
if (!coSDT) System.out.println(" - SĐT không hợp lệ");
if (!coDiaChi) System.out.println(" - Thiếu địa chỉ");
if (tongTien <= 0) System.out.println(" - Tổng tiền không hợp lệ");
if (!dongYDieuKhoan) System.out.println(" - Chưa đồng ý điều khoản");
}
}
}
Bài Tập 4: Khuyến Mãi Đặc Biệt
public class KhuyenMaiDacBiet {
public static void main(String[] args) {
int ngay = 15;
int thang = 10; // Tháng 10
boolean laKhachHangMoi = true;
int tongTien = 150000;
System.out.println("🎁 KIỂM TRA KHUYẾN MÃI:\n");
// Khuyến mãi 1: Ngày 1-15 hàng tháng VÀ khách mới
boolean km1 = (ngay >= 1 && ngay <= 15) && laKhachHangMoi;
// Khuyến mãi 2: Tháng 10-12 (cuối năm) VÀ đơn >= 100k
boolean km2 = (thang >= 10 && thang <= 12) && tongTien >= 100000;
// Khuyến mãi 3: Ngày 8 HOẶC ngày 18 (may mắn)
boolean km3 = ngay == 8 || ngay == 18;
if (km1 || km2 || km3) {
System.out.println("🎉 CÓ KHUYẾN MÃI!\n");
if (km1) {
System.out.println("✅ KM Khách Mới (đầu tháng)");
System.out.println(" → Giảm 25%");
}
if (km2) {
System.out.println("✅ KM Cuối Năm");
System.out.println(" → Giảm 15%");
}
if (km3) {
System.out.println("✅ KM Ngày May Mắn");
System.out.println(" → Tặng 1 ly miễn phí");
}
} else {
System.out.println("Không có khuyến mãi");
}
}
}
⚠️ Lỗi Thường Gặp
Lỗi 1: Nhầm & Với &&
// ❌ SAI: Dùng & (bitwise) thay vì && (logical)
boolean a = true;
boolean b = false;
boolean result = a & b; // ⚠️ Hoạt động nhưng không short-circuit
// ✅ ĐÚNG: Dùng &&
boolean result = a && b; // ✅ Short-circuit
Lỗi 2: Thứ Tự Ưu Tiên
// ❌ SAI: Thiếu dấu ngoặc
boolean coTien = true;
boolean coThe = false;
boolean laVIP = true;
// && ưu tiên hơn ||
boolean ok = coTien || coThe && laVIP; // (coTien) || (coThe && laVIP)
// ✅ ĐÚNG: Dùng dấu ngoặc rõ ràng
boolean ok = (coTien || coThe) && laVIP;
Lỗi 3: Quên Kiểm Tra null
// ❌ SAI: Không check null trước
String ten = null;
if (ten.length() > 0 && ten.equals("VIP")) { // NullPointerException!
System.out.println("VIP");
}
// ✅ ĐÚNG: Check null trước (short-circuit)
if (ten != null && ten.length() > 0 && ten.equals("VIP")) {
System.out.println("VIP");
}
Lỗi 4: Phủ Định Phức Tạp
// ❌ SAI: Khó đọc
boolean hetHang = true;
boolean dongCua = true;
if (!(hetHang || dongCua)) { // Khó hiểu!
System.out.println("OK");
}
// ✅ ĐÚNG: Dùng De Morgan's Law
if (!hetHang && !dongCua) { // Rõ ràng hơn!
System.out.println("OK");
}
💡 Bí Quyết Của Barista
- && = Cả hai phải đúng: Dùng khi cần tất cả điều kiện
- || = Một trong hai đúng: Dùng khi chỉ cần 1 điều kiện
- ! = Đảo ngược: Phủ định điều kiện
- Short-circuit: && và || dừng sớm khi biết kết quả
- Dấu ngoặc: Làm rõ thứ tự khi kết hợp nhiều toán tử
- Check null trước: Tránh NullPointerException
🎓 Bạn Đã Học Được
- ✅ 3 toán tử logic:
&&,||,! - ✅ && = AND - Cả 2 phải true
- ✅ || = OR - 1 trong 2 true
- ✅ ! = NOT - Đảo ngược boolean
- ✅ Short-circuit evaluation
- ✅ Kết hợp nhiều điều kiện
- ✅ Thứ tự ưu tiên: ! > && > ||
☕ Món Tiếp Theo
Đã biết kết hợp điều kiện! Giờ học về toán tử gán:
👉 Toán Tử Gán - Assignment Operators
💡 Lời Khuyên Cuối: Logical operators như công thức phối trộn trong quán - biết kết hợp đúng sẽ tạo ra hương vị hoàn hảo!