Tong Hoang Vu
Tong Hoang Vu's blog

Tong Hoang Vu's blog

Dùng method có sẵn làm lambda với method reference

Dùng method có sẵn làm lambda với method reference

Java Stream API

Tong Hoang Vu's photo
Tong Hoang Vu
·Sep 6, 2021·

3 min read

Subscribe to my newsletter and never miss my upcoming articles

Lambda là một cách để viết implementation cho functional interface khá là tiện rồi. Tuy nhiên, đôi lúc bạn sẽ thấy nếu chỉ dùng lambda thì hơi bị rườm rà, trong khi method có sẵn rồi. Lúc này method reference sẽ phát huy tác dụng.

1. Giới thiệu sơ lược

Ví dụ đi nhé, chúng ta muốn in ra hết các tên trong stream. Và đây là hai cách dùng lambda và dùng method reference.

List<String> names = List.of("John", "Josie");

// Dùng lambda gọi tới lệnh in
names.streams()
    .forEach(name -> System.out.println(name));

// Dùng method reference
names.stream()
    .forEach(System.out::println);

Như bạn thấy ở trên, với những trường hợp mà logic lambda quá đơn giản, chỉ là gọi tới method khác có cấu trúc giống vậy thì nên dùng method reference hơn.

wMtxW.png

Như ở ví dụ trên, bạn thấy được cú pháp của method reference.

Gồm có target reference, hai dấu hai chấm :: và tên method. Chú ý method reference không có ngoặc tròn nhé ()

Method reference cũng trả về implementation của functional interface tương ứng, giống như lambda vậy.

2. Các loại method reference

Có 3 dạng method reference, tùy vào target trỏ tới:

  • Trỏ tới instance method
  • Trỏ tới static method
  • Trỏ tới constructor

Hai dạng đầu thì dễ rồi, trỏ tới instance method thì target là object, còn static thì target là class thôi. Như ví dụ sau cho dễ hiểu.

class Test {
    public boolean checkAge(int age) {
        return age > 18;
    }

    public static boolean checkAgeStatic(int age) {
        return age > 18;
    }
}
...
Predicate<Integer> firstCheck = new Test()::checkAge;
Predicate<Integer> secondCheck = Test::checkAgeStatic;

Thực tế bạn ít khi trỏ tới method của riêng bạn, thay vào đó sẽ trỏ vào những method có sẵn của Java. Dưới đây là một số ví dụ.

Function<String, Integer> getLength = String::length;

Bạn sẽ thắc mắc ủa length() đâu phải static method, mà là instance method tại sao lại không new String() nào vậy? Thực ra viết giống trỏ tới static method thế thôi, nhưng lại là trỏ tới instance method của chính param đưa vào. Nó giống thế này.

Function<String, Integer> getLength = str -> str.length();

Mình cũng hơi bị rối chỗ này, Java cú pháp trong trường hợp này thực sự chưa tốt. Đúng ra phải có cái gì đó như this::length chứ nhỉ? Phần confuse này các bạn xem thêm dưới comment nhé.

3. Trỏ tới constructor

Đây là dạng method reference đặc biệt nên mình tách riêng ra một phần. Cũng vì phần trước khá dài rồi 😂 Về phần này cũng đơn giản thôi, method reference trỏ tới constructor thường dùng để return về một object mới. Các tham số của constructor sẽ tương ứng với tham số của lambda (thường là 1)..

// Thông cảm nhé do ví dụ này là easy nhất rồi
// Đúng ra phải dùng static Integer::parseInt thì tốt hơn
Function<String, Integer> parseInt = Integer::new;

// Sẽ tương đương với
Function<String, Integer> parseInt = str -> new Integer(str);

Vậy là bài viết cũng xong, và đây cũng là kết thúc phần nền tảng của Stream API. Những bài tiếp theo mình sẽ đi thẳng vô trọng tâm của Stream API luôn nhé. Cảm ơn các bạn đã ủng hộ, nhớ Like và Share nhiều nhiều cho tui vui nhé 😘

 
Share this