Backend

99 Ngày Java — Ngày 04: Toán tử & biểu thức

SSite Admin
31 tháng 07, 2026 5 phút đọc 163 lượt xem
99 Ngày Java — Ngày 04: Toán tử & biểu thức

Hôm qua bạn đã có những chiếc hộp dữ liệu — biến và 8 kiểu nguyên thủy. Hôm nay ta cho chúng "nói chuyện" với nhau bằng toán tử: cộng trừ nhân chia, so sánh, logic, toán tử 3 ngôi — và bẫy độ ưu tiên khiến 2 + 3 * 4 không bằng 20.

Sketchnote Ngày 04: Toán tử và biểu thức trong Java

Toán tử số học

Năm toán tử quen thuộc: + - * / %. Nhưng Java có một bất ngờ lớn cho người mới: hai số nguyên chia nhau ra số nguyên — phần thập phân bị cắt bỏ không thương tiếc:

int a = 7, b = 2;
System.out.println(a + b);   // 9
System.out.println(a - b);   // 5
System.out.println(a * b);   // 14
System.out.println(a / b);   // 3   — chia NGUYÊN: phần thập phân bị cắt!
System.out.println(a % b);   // 1   — số dư (modulo)
System.out.println(7.0 / 2); // 3.5 — có double tham gia là chia thực

Toán tử % (lấy dư) hữu ích hơn vẻ ngoài của nó: n % 2 == 0 kiểm tra số chẵn, index % size quay vòng chỉ số mảng, seconds % 60 tách phút–giây. Còn phép chia nguyên 7 / 2 = 3 là nguồn bug kinh điển khi tính trung bình, tỷ lệ phần trăm — chỉ cần một vế là double (viết 7.0 hoặc cast) là phép chia thành chia thực.

++ và -- : prefix vs postfix

int i = 5;
System.out.println(i++); // in 5, SAU ĐÓ i mới thành 6 (postfix)
System.out.println(++i); // i thành 7 TRƯỚC, rồi mới in 7 (prefix)

int j = 5;
int k = j++ + ++j;       // đọc được, nhưng đừng viết thế này!
  • i++ (postfix) — dùng giá trị cũ trước, tăng sau.

  • ++i (prefix) — tăng trước, rồi mới dùng giá trị mới.

  • Đứng một mình (i++;) thì hai dạng như nhau — và đó là cách dùng nên theo: đừng nhét ++ vào giữa biểu thức phức tạp.

Toán tử gán kết hợp

x += 5 là cách viết gọn của x = x + 5 — tương tự có -=, *=, /=, %=. Một chi tiết ít người biết: toán tử gán kết hợp tự ép kiểu ngầmbyte b = 10; b += 1; chạy ngon, trong khi b = b + 1; lỗi compile vì b + 1int. Chuyện ép kiểu này chính là chủ đề của Ngày 05.

So sánh & logic — và short-circuit

Toán tử so sánh (==, !=, >, <, >=, <=) trả về boolean, rồi được ghép bằng logic && (VÀ), || (HOẶC), ! (PHỦ ĐỊNH):

int age = 20;
boolean hasTicket = true;
boolean canEnter = age >= 18 && hasTicket;   // true

// Short-circuit: vế phải KHÔNG chạy nếu vế trái đã đủ kết luận
String name = null;
if (name != null && name.length() > 0) {
    // an toàn: name.length() chỉ chạy khi name != null
}

Short-circuit là tính năng chứ không phải chi tiết vặt: && thấy vế trái false là dừng ngay, || thấy vế trái true là dừng ngay. Nhờ vậy mẫu name != null && name.length() > 0 trở thành thành ngữ chống NullPointerException mà bạn sẽ gặp ở mọi codebase Java. Lưu ý: với String, so sánh nội dung phải dùng .equals() chứ không phải == — Ngày 09 sẽ mổ xẻ kỹ.

Màn hình code đầy biểu thức — nơi toán tử làm việc ngày đêm

Toán tử 3 ngôi

Toán tử duy nhất nhận 3 toán hạng: điều_kiện ? giá_trị_nếu_đúng : giá_trị_nếu_sai — một biểu thức if-else thu gọn:

int score = 75;
String result = score >= 50 ? "Đậu" : "Rớt";   // "Đậu"

// Tương đương if-else 4 dòng — nhưng chỉ nên dùng khi NGẮN GỌN
int max = a > b ? a : b;

Quy tắc vàng: 3 ngôi dùng cho lựa chọn ngắn, một tầng. Lồng 3 ngôi trong 3 ngôi là cách nhanh nhất khiến đồng nghiệp muốn "nói chuyện riêng" với bạn — khi logic phức tạp, quay về if-else (học kỹ ở Ngày 06).

Độ ưu tiên — khi nghi ngờ, thêm ngoặc

int x = 2 + 3 * 4;        // 14 — nhân trước, cộng sau
int y = (2 + 3) * 4;      // 20 — ngoặc thắng tất cả

boolean t = true || false && false;   // true — && trước ||
boolean u = (true || false) && false; // false — ngoặc đổi kết quả
  • Thứ tự đại khái cần nhớ: !* / %+ - → so sánh → &&|| → gán = cuối cùng.

  • Không ai được thưởng vì thuộc lòng bảng ưu tiên 15 tầng — cứ thêm ngoặc cho người đọc (và chính bạn 6 tháng sau).

Bài tập nhỏ

  • Không chạy code, đoán kết quả: 9 / 4, 9 % 4, 9.0 / 4 — rồi chạy kiểm tra.

  • Cho int i = 10;System.out.println(i++ + ++i) in gì? Giải thích từng bước.

  • Viết biểu thức kiểm tra một năm nhuận: chia hết cho 4 nhưng không chia hết cho 100, hoặc chia hết cho 400.

  • Dùng toán tử 3 ngôi viết hàm trả về trị tuyệt đối của một số int.

Kết luận

Bạn đã nắm đủ bộ toán tử: số học và cú lừa chia nguyên, ++/-- hai dạng, so sánh, logic short-circuit, 3 ngôi và quy tắc "thêm ngoặc khi nghi ngờ". Ngày 05, ta giải quyết câu hỏi treo từ hôm nay: chuyện gì xảy ra khi các kiểu khác nhau gặp nhau trong một biểu thức — ép kiểu (casting), widening vs narrowing và bẫy mất mát dữ liệu. Hẹn gặp lại!

S

Site Admin

Engineer and writer. Building things with TypeScript and distributed systems.

Bình luận (0)

Bạn cần đăng nhập bằng Google để bình luận.

Hãy là người bình luận đầu tiên.

Bài viết liên quan

99 Ngày Java — Ngày 58: Optional

Optional là công cụ cho kiểu trả về — không field, không tham số, không bọc collection; chuỗi map/flatMap/filter thay kim tự tháp if; orElse luôn tính tham số còn orElseGet lười, orElseThrow cho “không có là lỗi” — và các anti-pattern isPresent + get, orElse(null).

23 thg 9, 20269 phút9
99 Ngày Spring — Ngày 58: Spring Boot Actuator

Boot 3 mặc định chỉ lộ health; bản đồ endpoint an toàn và nguy hiểm; HealthIndicator tự viết với liveness tách khỏi readiness cho Kubernetes, info từ build và git, metrics Micrometer với tag hữu hạn — và ba lớp khóa: cổng riêng, SecurityFilterChain với EndpointRequest, exclude env/heapdump/threaddump.

23 thg 9, 202610 phút5
So sánh EasyExcel và Apache Fesod: khác biệt thật nằm ở đâu?

Fesod là hậu duệ của EasyExcel, cùng engine SAX/SXSSF. Khác biệt kiểm chứng được: vòng đời dự án, POI 5.2.5 vs 5.5.1, các API mới (numRows, csv(), headerMergeStrategy) và độ bền với file xấu — không phải hiệu năng gấp nhiều lần.

23 thg 9, 20268 phút1