# 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:
        
        ```java
        (parameters) -> expression
        (parameters) -> { statements; }
        ```
        
    * Ví dụ:
        
        ```java
        // 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.function` như `Predicate`, `Function`, `Consumer`, và `Supplier`.
        
    * Định nghĩa một Functional Interface:
        
        ```java
        @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:
        
        ```java
        @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:
        
        ```java
        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ụ:
        
        ```java
        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**:
        
        ```java
        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**
    
    ```java
    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**
    
    ```java
    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.
