Functional Interface trong Java
1. Functional Interface
Functional Interface là một khái niệm mới được đưa vào Java từ phiên bản 8, nó là một interface có duy nhất một phương thức trừu tượng. Các biểu thức Lambda thường được sử dụng để tạo nhanh một đối tượng của một Functional Interface.
Dưới đây là một Functional Interface, với một phương thức trừu tượng duy nhất:
package org.o7planning.ex;
public interface Greeting {
String greeting(String name);
default String hello(String name) {
return "Hello " + name;
}
}
Nếu một interface được thiết kế với mục đích là một functional interface bạn nên sử dụng annotation @FunctionalInterface để chú thích (anotate) cho nó, mặc dù điều này là không bắt buộc nhưng nó giúp những người khác dễ dàng hiểu được ý tưởng thiết kế của bạn, đồng thời nó cũng hỗ trợ trình biên dịch (compiler) thông báo các sai sót của bạn trong quá trình phát triển ứng dụng. Chẳng hạn trình biên dịch sẽ thông báo lỗi cho bạn nếu có một interface được chú thích bởi @FunctionalInterface nhưng có nhiều hơn một phương thức trừu tượng.
package org.o7planning.ex;
@FunctionalInterface
public interface Greeting {
String greeting(String name);
default String hello(String name) {
return "Hello " + name;
}
}
Tiếp tục với ví dụ trên. Trước Java 8, để sử tạo một đối tượng Greeting bạn phải tạo một lớp, sau đó implement phương thức trừu tượng của Greeting, điều này khá dài dòng.
UsingGreetingBeforeJ8.java
package org.o7planning.ex;
public class UsingGreetingBeforeJ8 {
public static void main(String[] args) {
// Create Greeting object:
Greeting obj = new Greeting() {
@Override
public String greeting(String name) {
return "Hi " + name;
}
};
System.out.println(obj.greeting("Tran"));
System.out.println(obj.hello("Tran"));
}
}
Về cơ bản Functional Interface chỉ bao gồm 1 phương thức trừu tượng duy nhất, vì vậy bạn chỉ cần implement duy nhất phương thức này. Biểu thức Lambda của Java 8 giúp bạn viết lại ví dụ trên ngắn gọn hơn.
UsingGreetingJ8A.java
package org.o7planning.ex;
public class UsingGreetingJ8A {
public static void main(String[] args) {
// Create Greeting object with Lambda expression:
Greeting obj = (String name) -> {
return "Hi " + name;
};
System.out.println(obj.greeting("Tran"));
System.out.println(obj.hello("Tran"));
}
}
Các kiểu dữ liệu của các tham số trong phương thức trừu tượng của Greeting đều đã biết vì vậy không cần thiết phải viết lại chúng. Chúng ta có thể viết lại ví dụ trên ngắn gọn hơn:
Greeting obj = (name) -> {
return "Hi " + name;
};
Nếu phương thức trừu tượng có duy nhất một tham số, bạn có thể không cần viết dấu ngặc đơn (parentheses) ( ) trong biểu thức Lambda:
Greeting obj = name -> {
return "Hi " + name;
};
Nếu nội dung của phương thức chỉ bao gồm duy nhất một biểu thức bạn có thể không cần dấu ngặc nhọn (braces) { } và cũng không cần viết từ khoá "return".
Greeting obj = name -> "Hi " + name;
Cuối cùng code của ví dụ trên đã ngắn hơn rất nhiều:
UsingGreetingJ8.java
package org.o7planning.ex;
public class UsingGreetingJ8 {
public static void main(String[] args) {
// Create Greeting object with Lambda expression:
Greeting obj = name -> "Hi " + name;
System.out.println(obj.greeting("Tran"));
System.out.println(obj.hello("Tran"));
}
}
Output:
Hi Tran
Hello Tran
2. Examples
Tiếp theo chúng ta sẽ xem một vài Functional Interface bao gồm hợp lệ và không hợp lệ, và giải thích tại sao chúng không hợp lệ:
Interface IEquals dưới đây không phải là một functional interface vì phương thức "public boolean equals(Object)" là một thành viên được thừa kế từ lớp Object. Vì vậy IEquals được coi là không có phương thức trừu tượng nào và không đủ điều kiện để được coi là một functional interface.
IEquals.java (Invalid!)
package org.o7planning.j8fi;
@FunctionalInterface
public interface IEquals {
boolean equals(Object other);
}
Hợp lệ:
IComparator.java (OK, Valid!)
package org.o7planning.j8fi;
@FunctionalInterface
public interface IComparator<T> {
int compareTwoObject(T obj, T other);
boolean equals(Object other);
}
Phương thức clone() của lớp Object là protected (Không phải public). Vì vậy interface IWithClone dưới đây được coi là một functional interface hợp lệ.
IWithClone.java (OK, Valid)
package org.o7planning.j8fi;
@FunctionalInterface
public interface IWithClone {
Object clone();
}
Interface CC trong hình minh hoạ ở trên là một functional interface hợp lệ vì các phương thức trừu tượng mà nó được thừa kế từ AA và BB là giống nhau.
Java cơ bản
- Tùy biến trình biên dịch java xử lý Annotation của bạn (Annotation Processing Tool)
- Lập trình Java theo nhóm sử dụng Eclipse và SVN
- Hướng dẫn và ví dụ Java WeakReference
- Hướng dẫn và ví dụ Java PhantomReference
- Hướng dẫn nén và giải nén trong Java
- Cấu hình Eclipse để sử dụng JDK thay vì JRE
- Phương thức String.format() và printf() trong Java
- Cú pháp và các tính năng mới trong Java 5
- Cú pháp và các tính năng mới trong Java 8
- Hướng dẫn sử dụng biểu thức chính quy trong Java
- Hướng dẫn lập trình đa luồng trong Java - Java Multithreading
- Thư viện điều khiển các loại cơ sở dữ liệu khác nhau trong Java
- Hướng dẫn sử dụng Java JDBC kết nối cơ sở dữ liệu
- Lấy các giá trị của các cột tự động tăng khi Insert một bản ghi sử dụng JDBC
- Hướng dẫn và ví dụ Java Stream
- Functional Interface trong Java
- Giới thiệu về Raspberry Pi
- Hướng dẫn và ví dụ Java Predicate
- Abstract class và Interface trong Java
- Access modifier trong Java
- Hướng dẫn và ví dụ Java Enum
- Hướng dẫn và ví dụ Java Annotation
- So sánh và sắp xếp trong Java
- Hướng dẫn và ví dụ Java String, StringBuffer và StringBuilder
- Hướng dẫn xử lý ngoại lệ trong Java - Java Exception Handling
- Hướng dẫn và ví dụ Java Generics
- Thao tác với tập tin và thư mục trong Java
- Hướng dẫn và ví dụ Java BiPredicate
- Hướng dẫn và ví dụ Java Consumer
- Hướng dẫn và ví dụ Java BiConsumer
- Bắt đầu với Java cần những gì?
- Lịch sử của Java và sự khác biệt giữa Oracle JDK và OpenJDK
- Cài đặt Java trên Windows
- Cài đặt Java trên Ubuntu
- Cài đặt OpenJDK trên Ubuntu
- Cài đặt Eclipse
- Cài đặt Eclipse trên Ubuntu
- Học nhanh Java cho người mới bắt đầu
- Lịch sử của bit và byte trong khoa học máy tính
- Các kiểu dữ liệu trong Java
- Các toán tử Bitwise
- Câu lệnh rẽ nhánh (if else) trong Java
- Câu lệnh rẽ nhánh switch trong Java
- Vòng lặp trong Java
- Mảng (Array) trong Java
- JDK Javadoc định dạng CHM
- Thừa kế và đa hình trong Java
- Hướng dẫn và ví dụ Java Function
- Hướng dẫn và ví dụ Java BiFunction
- Ví dụ về Java encoding và decoding sử dụng Apache Base64
- Hướng dẫn và ví dụ Java Reflection
- Hướng dẫn gọi phương thức từ xa với Java RMI
- Hướng dẫn lập trình Java Socket
- Các nền tảng nào bạn nên chọn để lập trình ứng dụng Java Desktop?
- Hướng dẫn và ví dụ Java Commons IO
- Hướng dẫn và ví dụ Java Commons Email
- Hướng dẫn và ví dụ Java Commons Logging
- Tìm hiểu về Java System.identityHashCode, Object.hashCode và Object.equals
- Hướng dẫn và ví dụ Java SoftReference
- Hướng dẫn và ví dụ Java Supplier
- Lập trình Java hướng khía cạnh với AspectJ (AOP)
Show More
- Hướng dẫn lập trình Java Servlet/JSP
- Các hướng dẫn Java Collections Framework
- Java API cho HTML & XML
- Các hướng dẫn Java IO
- Các hướng dẫn Java Date Time
- Các hướng dẫn Spring Boot
- Các hướng dẫn Maven
- Các hướng dẫn Gradle
- Các hướng dẫn Java Web Services
- Các hướng dẫn lập trình Java SWT
- Các hướng dẫn lập trình JavaFX
- Các hướng dẫn Java Oracle ADF
- Các hướng dẫn Struts2 Framework
- Các hướng dẫn Spring Cloud