Bài 2: Biểu thức Lambda và Functional Interfaces (Java 8)
Mục tiêu
Bài viết này nhằm mục đích giúp bạn hiểu và sử dụng biểu thức Lambda và Functional Interfaces trong Java 8, cung cấp các ví dụ cụ thể và so sánh với cách làm truyền thống.
Nội dung
1. Giới thiệu về biểu thức Lambda
Định nghĩa và cú pháp
Biểu thức Lambda là một khối mã có thể được truyền đi như một đối số, giống như một hàm ẩn danh trong các ngôn ngữ lập trình khác.
Cú pháp cơ bản:
(parameters) -> expression (parameters) -> { statements; }Ví dụ:
// Lambda expression with a single parameter and a single expression (int x) -> x + 1 // Lambda expression with multiple parameters and a block of statements (int x, int y) -> { int sum = x + y; return sum; }
Ưu điểm và ứng dụng
Giảm bớt mã nguồn boilerplate.
Tăng khả năng đọc và bảo trì mã.
Hỗ trợ lập trình hàm trong Java.
Thường được sử dụng với các API như Streams và Collections.
2. Functional Interfaces
Định nghĩa và cách sử dụng
Một Functional Interface là một interface chỉ chứa một phương thức trừu tượng.
Có thể được sử dụng làm đích cho biểu thức Lambda.
Java 8 giới thiệu một số Functional Interfaces trong gói
java.util.functionnhưPredicate,Function,Consumer, vàSupplier.Định nghĩa một Functional Interface:
@FunctionalInterface public interface MyFunctionalInterface { void myMethod(); }
Ví dụ cụ thể
Sử dụng biểu thức Lambda với một Functional Interface tùy chỉnh:
@FunctionalInterface interface MyFunctionalInterface { void myMethod(); } public class LambdaExample { public static void main(String[] args) { // Lambda expression implementing the abstract method MyFunctionalInterface myFunc = () -> System.out.println("Hello, Lambda!"); myFunc.myMethod(); } }Sử dụng biểu thức Lambda với các Functional Interface có sẵn:
import java.util.function.Predicate; public class LambdaExample { public static void main(String[] args) { Predicate<String> isEmpty = s -> s.isEmpty(); System.out.println(isEmpty.test("")); // Output: true System.out.println(isEmpty.test("Hello")); // Output: false } }
3. So sánh với cách làm truyền thống (Anonymous Classes)
Anonymous Classes
Trước Java 8, các interface thường được triển khai bằng cách sử dụng Anonymous Classes.
Ví dụ:
Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Hello, Anonymous Class!"); } }; new Thread(runnable).start();
So sánh với biểu thức Lambda
Biểu thức Lambda:
Runnable runnable = () -> System.out.println("Hello, Lambda!"); new Thread(runnable).start();Ưu điểm của Lambda:
Ngắn gọn và dễ đọc hơn.
Tránh được sự lặp lại không cần thiết.
Tăng tính biểu cảm của mã nguồn.
4. Sử dụng Lambda trong Collections và Streams
Sắp xếp danh sách với Lambda
import java.util.Arrays; import java.util.List; public class LambdaExample { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); // Sort names in alphabetical order using a Lambda expression names.sort((a, b) -> a.compareTo(b)); System.out.println(names); // Output: [Alice, Bob, Charlie] } }Sử dụng Lambda với Streams API
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class LambdaExample { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // Filter and map using Lambda expressions List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); System.out.println(evenNumbers); // Output: [2, 4] } }
Kết luận
Biểu thức Lambda và Functional Interfaces mang lại sự đơn giản và hiệu quả cho lập trình Java. Chúng giúp giảm bớt mã nguồn, tăng khả năng đọc và bảo trì, cũng như cung cấp cách tiếp cận lập trình hàm trong Java. Hiểu rõ và áp dụng đúng các tính năng này sẽ giúp bạn viết mã nguồn Java hiện đại và hiệu quả hơn.