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

🔗 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ênVí Dụ CaféKết Quả
&&AND (VÀ)coTien && coChoNgoiCả 2 đều true
||OR (HOẶC)isVIP || coMa1 trong 2 true
!NOT (KHÔNG)!hetHangĐảo ngược boolean

Truth Table - Bảng Chân Lý

AND (&&)

ABA && B
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse

OR (||)

ABA || B
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse

NOT (!)

A!A
truefalse
falsetrue

👨‍🍳 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

  1. && = Cả hai phải đúng: Dùng khi cần tất cả điều kiện
  2. || = Một trong hai đúng: Dùng khi chỉ cần 1 điều kiện
  3. ! = Đảo ngược: Phủ định điều kiện
  4. Short-circuit: && và || dừng sớm khi biết kết quả
  5. Dấu ngoặc: Làm rõ thứ tự khi kết hợp nhiều toán tử
  6. 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!