VieTopik
Tiếng HànTiếng Anh.NET (C#)Java
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
Java CoreCông cụ hằng ngày
Bài 16/19
5 phút

Lambda

Nội dung bài · 6 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Lambda nhiều câu lệnh
  4. 4.Thử ngay
  5. 5.Lỗi hay gặp
  6. 6.Tóm tắt

Lọc sản phẩm đắt hơn 100.000đ, tìm món đầu tiên còn hàng: mỗi việc cần truyền một điều kiện vào method. Viết hẳn một method có tên cho mỗi điều kiện thì quá dài. Lambda cho phép viết điều kiện đó ngay tại chỗ.

Khái niệm

➡️ Lambda: một method không tên viết gọn theo dạng tham số -> kết quả, dùng để truyền vào method khác hoặc gán vào biến.

📮 Function: kiểu dùng để lưu lambda nhận một giá trị và trả về kết quả, viết là Function<kiểu vào, kiểu ra>.

p -> p > 100000 đọc là: "nhận p, trả về p > 100000".

Ví dụ

// Main.java
void main() {
    Function<Long, Long> addVat =
        price -> price * 110 / 100;
    System.out.println(addVat.apply(100000L)); // 110000

    List<Long> prices = new ArrayList<>(
        List.of(5000L, 150000L, 30000L, 200000L));

    prices.removeIf(p -> p <= 100000);
    System.out.println(prices);   // [150000, 200000]
}
  • Function<Long, Long>: nhận Long, trả về Long. Kiểu đứng sau luôn là kiểu trả về. Trong < > viết Long chứ không viết long, giống List.
  • addVat.apply(100000L) chạy lambda với giá trị truyền vào.
  • prices.removeIf(p -> p <= 100000) truyền điều kiện vào removeIf. removeIf tự chạy lambda với từng phần tử và xoá phần tử cho kết quả true, ngay trên list gốc.

Lambda nhiều câu lệnh

Lambda cần nhiều câu lệnh thì đặt thân trong { } và dùng return như method:

// Main.java
void main() {
    Function<Long, Long> shippingFee = total -> {
        if (total >= 500000) {
            return 0L;
        }
        return 30000L;
    };
    System.out.println(shippingFee.apply(100000L));
    // 30000
}

Lambda một biểu thức như x -> x * 2 là cách viết gọn của x -> { return x * 2; }.

Thử ngay

Dán vào Main.java rồi chạy java Main.java:

// Main.java
void main() {
    Function<Integer, Integer> twice = x -> x * 2;
    Function<Integer, Boolean> isEven = x -> x % 2 == 0;

    System.out.println(twice.apply(twice.apply(3)));
    System.out.println(isEven.apply(7));
}

Đoán trước khi chạy: twice.apply(twice.apply(3)) ra 6 hay số khác?

Xem kết quả
12
false

twice.apply(3) ra 6, rồi twice.apply(6) ra 12. Lambda gọi lồng nhau như method bình thường.

Lỗi hay gặp

Dùng var cho lambda. Compiler không biết lambda thuộc kiểu gì, cũng không biết x là kiểu gì.

// SAI — lỗi compile: không suy ra được kiểu
var triple = x -> x * 3;
// ĐÚNG — khai báo rõ kiểu bằng Function
Function<Integer, Integer> triple = x -> x * 3;

Có ngoặc { } mà quên return. Lambda có thân trong { } phải có return như method.

// SAI — lỗi compile: thiếu return
Function<Integer, Integer> discount =
    x -> { x - 1000; };
// ĐÚNG
Function<Integer, Integer> discount =
    x -> { return x - 1000; };

Tóm tắt

  • Lambda là method không tên: tham số -> kết quả.
  • Lưu lambda bằng Function<vào, ra>, kiểu cuối là kiểu trả về, gọi bằng apply.
  • Lambda thường được truyền vào method khác làm điều kiện, như removeIf.
  • Lambda nhiều câu lệnh đặt trong { } và phải có return.

Tự kiểm tra

0/3 câu
Câu 1

Function<String, Integer> f = s -> s.length(); System.out.println(f.apply("shop")); In ra gì?

Câu 2

Khai báo nào đúng cho một lambda nhận Long và trả về Boolean?

Câu 3

names là một ArrayList<String>. names.removeIf(n -> n.startsWith("A")) làm gì?

enumStream cơ bản

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Lambda nhiều câu lệnh
  4. 4.Thử ngay
  5. 5.Lỗi hay gặp
  6. 6.Tóm tắt