Lambda
Nội dung bài · 6 mục
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ậnLong, trả vềLong. Kiểu đứng sau luôn là kiểu trả về. Trong< >viếtLongchứ không viếtlong, giốngList.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àoremoveIf.removeIftự 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
falsetwice.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ằngapply. - 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âuFunction<String, Integer> f = s -> s.length(); System.out.println(f.apply("shop")); In ra gì?
Khai báo nào đúng cho một lambda nhận Long và trả về Boolean?
names là một ArrayList<String>. names.removeIf(n -> n.startsWith("A")) làm gì?