Java 8 Method Reference (Phần 2)
Ở phần 1, mình đã giới thiệu qua 2 loại method preference - Method reference một static method - Method reference một instance method của một object có kiểu đặc biệt Giờ chúng ta sẽ tìm hiểu nốt 2 loại còn lại Method reference một instance method của một object đã tồn tại. Trong trường hợp ...
Ở phần 1, mình đã giới thiệu qua 2 loại method preference - Method reference một static method - Method reference một instance method của một object có kiểu đặc biệt Giờ chúng ta sẽ tìm hiểu nốt 2 loại còn lại
Method reference một instance method của một object đã tồn tại.
Trong trường hợp này, ta có một lambda expression như sau (args) -> obj.instanceMethod(args) Ta có chuyển thành method reference như sau obj::instanceMethod Lúc này, một instance xác định được sử dụng và nếu có argument thì sẽ được truyền ẩn như trường hợp của method static
class Car { private int id; private String color; } class Mechanic { public void fix(Car c) { System.out.println("Fixing car " + c.getId()); } }
Ta có phương thức
public void execute(Car car, Consumer<Car> c) { c.accept(car); }
Ta có thể gọi phương thức trên bằng cách sau
final Mechanic mechanic = new Mechanic(); Car car = new Car(); // Sử dụng anonymous class execute(car, new Consumer<Car>() { public void accept(Car c) { mechanic.fix(c); } }); // Sử dụng lambda expression execute(car, c -> mechanic.fix(c)); // Sử dụng method reference execute(car, mechanic::fix);
Mấu chốt ở trường hợp này là sử dụng bất kì object nào bằng anonymous class hoặc lambda expression và truyền argument cho instance method của object đó Một ví dụ khác của việc sử dụng Consumer
Consumer<String> c = System.out::println; c.accept("Hello");
Constructor method reference
Ở trường hợp này, ta có lambda expression như sau (args) -> new ClassName(args) Ta có thể chuyển thành method reference như sau ClassName::new Lamda expression tạo một object mới và ta chỉ cần reference constructor của class đó với từ khóa “new”. Ở trường hợp này, argument không được truyền trong method reference Hầu hết chúng ta sử dụng cú pháp này với 2 hoặc 3 interface trong java.util.function package Nếu constructor không nhân argument nào, ta sử dụng một Supplier
// Sử dụng anonymous class Supplier<List<String>> s = new Supplier() { public List<String> get() { return new ArrayList<String>(); } }; List<String> l = s.get(); // Sử dụng lambda expression Supplier<List<String>> s = () -> new ArrayList<String>(); List<String> l = s.get(); // Sử dụng method reference Supplier<List::new; List<String> l = s.get();
Nếu constructor nhận một argument, ta sử dụng Function interface.
// Sử dụng anonymous class Function<String, Integer> f = new Function<String, Integer>() { public Integer apply(String s) { return new Integer(s); } }; Integer i = f.apply(100); //Sử dụng lambda expression Function<String, Integer> f = s -> new Integer(s); Integer i = f.apply(100); // Sử dụng method reference Function<String, Integer> f = Integer::new; Integer i = f.apply(100);
Nếu constructor nhận 2 argument. ta sử dụng BiFunction interface
// Sử dụng anonymous class BiFunction<String, String, Locale> f = new BiFunction<String, String, Locale>() { public Locale apply(String lang, String country) { return new Locale(lang, country); } }; Locale loc = f.apply("en","UK"); // Sử dụng lambda expression BiFunction<String, String, Locale> f = (lang, country) -> new Locale(lang, country); Locale loc = f.apply("en","UK"); // Sử dụng method reference BiFunction<String, String, Locale> f = Locale::new; Locale loc = f.apply("en","UK");
Nếu constructor cần nhiều hơn 2 argument thi ta cần viết custom interface theo nhu cầu của mình Nhìn chung, reference một constructor cũng tương tự việc reference một static method. Khác biệt ở đây là method name của constructor là “new”
Kết luận
Như đã giới thiệu lúc đâu, hãy sử dụng method reference nếu chúng giúp code bạn rõ ràng hơn. Ví dụ ta có thể tránh được việc viết nhiều code trong một method bằng cách nhóm code vào 1 static method và tạo reference đến method thay vì phải gọi class chứa nó hay dùng lambda expression. Tuy nhiên method reference chỉ thực sự hiệu quả và sử dụng được hết tính năng của nó chỉ khi kết hợp với một tính năng mới trong java 8 đó là streams Cảm ơn các bạn đã theo dõi
Bài viết được dịch từ link