Java 8 ra đười với hàng loạt những tính năng mới, hôm nay chúng ta sẽ tìm hiểu về Lambda Expression. Một trong những tính năng hay nhất của Java 8.
Vậy Lambda Expression là cái gì?
Lambda Expression được sinh ra nhằm biến Java trở nên dễ viết hơn dưới dạng Functional Programming.
Hiểu một cách đơn giản Lambda Expression để mô tả một function mà function này sẽ không thuộc về bất cứ class nào cả.
Đầu tiên chúng ta tìm hiểu về Single Method Interface.
Dịch sát nghĩa chúng ta có thể hiểu, Single Method Interface là một Interface, mà trong Interface đó được define chỉ một method duy nhất.
Trong Functional Programming, chúng ta thường hiện thực những Event Listener, trong Java chúng ta thường sử dụng Single Method Interface để mà định nghĩa Event Listener.
Nào cũng xem thử đoạn code dưới đây.
public interface MessageListener { | |
public void onMessage(String sender, String receiver, String message); | |
} |
Interface này define một method duy nhất với nhiệm vụ là ngóng message được gửi lên server với 3 tham số là sender, reciever và nội dung message.
Tưởng tượng, bạn có một Class là ChatServer, trong ChatServer sẽ chứa một MessageListener để ngóng sự kiện message được gửi lên, chúng ta implemet ChatServer như sau.
public class ChatServer { | |
public void addMessageListener(MessageListener listener) { | |
// your code goes here | |
} | |
} |
Trươc khi Java 8 ra đời, bạn phải implement Interface trên như thế này, với cách implement này bạn sử dụng một Anonymous Interface Implementation để truyền vào hàm addMessageListener().
ChatServer server = new ChatServer(); | |
server.addMessageListener(new MessageListener() { | |
public void onMessage(String sender, String receiver, String message) { | |
System.out.println("Message: " + message); | |
// your code goes here | |
} | |
}); |
Nào, để xem Java 8 làm được gì.
Với Java 8, cụ thể là với Lambda Expression bạn có tối giản đoạn code trên như sau.
ChatServer server = new ChatServer(); | |
server.addMessageListener( | |
(sender, reciever, message) -> System.out.println("Message: " + message); | |
); |
Đây, “->” cái này chính là Lambda Expression mà chúng ta đang nói tới.
Chúng ta có thể thấy Lambda Expression được đưa vào như là một tham số của addMessageListener().
Chắc các bạn cũng đã hiểu Lamda Expression 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 Lambda Expression hay còn có thể hiểu Lambda Parameters
Cũng như method, Lambda Expression có thể truyền vào bao nhiều tham số tùy ý.
Các tham số của Lambda Expression cũng tương tự như Single Method Interface mà nó thay thế cho.
Lambda Expression 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ố.
() -> System.out.println("Zero parameter lambda"); |
Chú ý rằng, cặp ngoặc đơn () để thể hiện Lambda Expression không nhận tham số nào cả.
Trường hợp có một tham số.
(param) -> System.out.println("One parameter: " + param); |
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.
param -> System.out.println("One parameter: " + param); |
Trường hợp có nhiều tham số.
Trong trường hợp Lambda Expression 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.
(param1, param2) -> System.out.println("Multiple parameters: " + param1 + ", " + param2); |
Ngoài ra tham số truyền vào Lambda Expression 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 Functional Interface 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.
(Message message) -> System.out.println("Message: " + message.getText()); |
Giờ chúng ta đã biết về cách dùng Lambda Expression cũng như về tham số truyền vào Lambda Expresion. Vậy nếu Fucntion Interface 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 Lambda Expression nằm phía bên phải đấu “->”.
(sender, receiver, message) -> System.out.println("Message: " + message); |
Nếu sử dụng nhiều lệnh trong phần thân hàm của Lambda Expression, đơn giản chúng ta chỉ cần viết chúng trong cặp ngoặc nhọn {}.
(sender, receiver, message) -> { | |
System.out.println("Sender: " + sender); | |
System.out.println("Receiver: " + receiver); | |
System.out.println("Message: " + message); | |
} |
Ắ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 Lambda trả về một giá trị nào đó. Đơn giản thôi, bạn có thể trả về giá trị trong thâm hàm của Lambda Expression bằng lệnh return như bình thường.
(param) -> { | |
System.out.println("Param: " + param); | |
return param; | |
} |
Trong trường hợp này.
(number1, number2) ->; { return number1 > number2; }
Bạn có thể viết ngắn gọn hơn bằng cách.
(number1, number2) -> number1 > number2;
Ngoài ra Lambda Expression cũng được sử dụng như sau.
public interface Comparator { | |
public boolean compare(int number1, int number2); | |
} | |
Comparator comparator = (number1, number2) -> number1 > number2; | |
boolean result = comparator.compare(1, 2); |
Chúng ta có thể hiểu, đoạn code đầu tiên ta khai báo Functional Interface. Đoạn code thứ 2, ta khai báo Lambda Expresion. Đoạn cuối cùng chúng ta thấy Lambda Expression được gọi như thế nào.
Chúc các bạn vui với Lambda Expression.
Hi anh!
Em có một thảo luận nhỏ liên quan đến khái niệm Single Method Interface. Theo như em được biết thì biểu thức Lambda phải đi kèm với khái niệm @FunctionalInterface. Khái niệm này được đưa vào Java 1.8 nhưng được sửa đổi lại khi từ khóa default ra đời. Theo đó thì một functionalInterface là một interface mà nó chỉ có đúng 1 abstract method. Nó có thể có nhiều method khác và các method này phải được đặt ở dạng default. Nếu ý hiểu theo Single Method Interface thì mình bị mất đi cách triển khai biểu thức Lambda theo cách của @FunctionalInterface trong java 8 đúng không ạh?
Em note thêm một chút là Java 1.8 là Java 8 nhé. Để tránh hiểu nhầm. :)