Biểu thức Lambda - Một trong những tính năng hay nhất của Java 8

17:23 31-08-2017BKAP Media

Biểu thức Lambda được sinh ra nhằm biến Java trở nên dễ viết hơn dưới dạng Lập trình chức năng (Functional Programming).



Hiểu một cách đơn giản biểu thức Lambda để mô tả một hàm mà hàm này sẽ không thuộc về bất cứ lớp nào cả.

Đầu tiên chúng ta tìm hiểu về giao diện phương thức đơn (Single Method Interface).

Chúng ta có thể hiểu, Single Method Interface là một giao diện, mà trong giao diện đó chỉ định nghĩa một phương thức duy nhất.

Trong lập trình chức năng, chúng ta thường hiện thực những trình lắng nghe sự kiện (event listener), trong Java chúng ta sử dụng Single Method Interface để mà định nghĩa trình lắng nghe sự kiện như vậy.

Hãy xem code dưới đây:

 

Tưởng tượng, bạn có một lớp là ChatServer, trong lớp ChatServer sẽ chứa một trình lắng nghe sự kiện để bắt sự kiện message được gửi lên, chúng ta thực thi lớp ChatServer như sau:Giao diện này định nghĩa một phương thức duy nhất với nhiệm vụ là lắng nghe thông điệp được gửi lên server với 3 tham số là sender, reciever và nội dung message.

Trươc khi Java 8 ra đời, bạn phải thực thi giao diện trên như vậy, với cách thực thi này bạn đã sử dụng thực thi của giao diện không tên (Anonymous interface) để truyền vào hàm addMessageListener().

Với Java 8, cụ thể là với biểu thức Lambda bạn có thể tối giản đoạn code trên như sau:
 

Chúng ta có thể thấy biểu thức Lambda được đưa vào như là một tham số của phương thức addMessageListener().
Ở đây, kí hiệu “->”chính là biểu thức Lambda mà chúng ta đang nói tới.

Đến đây phần nào các bạn cũng đã hiểu biểu thức Lamda là gì và được sử dụng như thế nào.

Tiếp theo chúng ta sẽ tìm hiểu về các truyền tham số vào biểu thức Lambda hay còn có thể hiểu là  các tham số của biểu thức Lambda

Cũng như phương thức, biểu thức Lambda có thể truyền vào bao nhiêu tham số tùy ý.

Các tham số của biểu thức Lambda cũng tương tự như Single Method Interface mà nó thay thế cho.

Biểu thức Lambda có thể không có tham số, một tham số hoặc nhiều tham số.

Trường hợp không có tham số:

 

Chú ý rằng, cặp ngoặc đơn () để thể hiện biểu thức Lambda không nhận tham số nào cả.

Trường hợp có một tham số.

Tham số sẽ được đặt trong cặp ngoặc đơn ().

Đối với trường hợp một tham số chúng ta cũng có thể lược bỏ đi cặp ngoặc đơn này.Tham số sẽ được đặt trong cặp ngoặc đơn ().

Trường hợp có nhiều tham số:

Trong trường hợp biểu thức Lambda nhận nhiều tham số, chúng ta phải đặt hết tham số trong cặp ngoặc đơn (). Chỉ trường hợp một tham số mới có thể lược bỏ cặp ngoặc đơn này.

Ngoài ra tham số truyền vào biểu thức Lambda cũng có thể khai báo kiểu dữ liệu như sau:
Viêc khai báo kiểu dữ liệu là cân thiết trong trường hợp trình biên dịch không thể tìm thấy giao diện chức năng nào phù hợp. Đừng lo lắng vì bạn không biết khi nào nên khai báo, khi nào không, bởi vì trình biên dịch sẽ nhắc nó cho bạn.
Cách khai báo kiểu dữ liệu đơn giản như sau:

Nhìn các đoạn code ở trên chắc hẳn các bạn đều biết phần thân hàm của biểu thức Lambda nằm phía bên phải đấu “->”.Giờ chúng ta đã biết về cách dùng biểu thức Lambda cũng như về tham số truyền vào biểu thức Lambda. Vậy nếu giao diện chức năng phải thực hiện nhiều lệnh thì ta phải làm thế nào, chúng ta cùng tìm hiểu về phần thân hàm, Lambda Function Body.

Nhìn các đoạn code ở trên chắc hẳn các bạn đều biết phần thân hàm của biểu thức Lambda nằm phía bên phải đấu “->”.
Nếu sử dụng nhiều lệnh trong phần thân hàm của biểu thức Lambda Expression, đơn giản chúng ta chỉ cần viết chúng trong cặp ngoặc nhọn {}.

Ắt hẳn các bạn đang thắc mắc, nãy giờ Lambda Expression trả về void, vậy thì phải làm thế nào nếu muốn biểu thức Lambda trả về một giá trị nào đó. Đơn giản thôi, bạn có thể trả về giá trị trong thân hàm của biểu thức Lambda bằng lệnh return như bình thường.

Trong trường hợp này.

Bạn có thể viết ngắn gọn hơn bằng cách.

Ngoài ra biểu thức Lambda cũng được sử dụng như sau.

Chúng ta có thể hiểu, đoạn code đầu tiên ta khai báo giao diện chức năng. Đoạn code thứ 2, ta khai báo biểu thức Lambda. Đoạn cuối cùng chúng ta thấy biểu thức Lambda được gọi như thế nào.

Một số ví dụ về sử dụng biểu thức Lambda:

Ví dụ 1:
Ví dụ 2

Ví dụ 3

 

Một ví dụ phức tạp hơn là ta sử dụng interface Predicate để in các phần tử trong danh sách trên theo những tiêu chí khác nhau.

import java.util.Arrays;

import java.util.List;

import java.util.function.Predicate;

 

public class Main {

 

    public static void main(String [] a)  {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

 

        System.out.print("Print all numbers: ");

        evaluate(list, (n)->true);// test(n) luôn return true

 

        System.out.print("Print no numbers: ");

        evaluate(list, (n)->false);// test(n) luôn return false

 

        System.out.print("Print even numbers: ");

        evaluate(list, (n)-> n%2 == 0 );// test(n) return true nếu n chẵn

 

        System.out.print("Print odd numbers: ");

        evaluate(list, (n)-> n%2 == 1 );// test(n) return true nếu n  lẻ

 

        System.out.print("Print numbers greater than 5: ");

        evaluate(list, (n)-> n > 5 );// test(n) return true nếu n > 5

    }

 

    public static void evaluate(List<Integer> list, Predicate<Integer> predicate) {

        for(Integer n: list)  {

            if(predicate.test(n)) {

                System.out.print(n + " ");

            }

        }

    }

}

 

Output như sau:

Print all numbers: 1 2 3 4 5 6 7                 

Print no numbers:

Print even numbers: 2 4 6

Print odd numbers: 1 3 5 7

Print numbers greater than 5: 6 7

Giảng viên: Nguyễn Duy Quang

   0968276996
< wire:id="BkfWpNH2OXGcI0PbOgi2" wire:initial-data="{"fingerprint":{"id":"BkfWpNH2OXGcI0PbOgi2","name":"embedded.footer","locale":"vn"},"effects":{"listeners":[]},"serverMemo":{"children":[],"errors":[],"htmlHash":"26380eb1","data":[],"dataMeta":[],"checksum":"69963feabc9840f72959ebde0dee5270a71f1e16d242bd57d17b305c3b0efb5a"}}"!-- Messenger Plugin chat Code -->