1. Metode fungsi

Jika antarmuka hanya memiliki satu metode , variabel dari tipe antarmuka tersebut dapat diberi nilai yang diberikan oleh ekspresi lambda (fungsi lambda). Antarmuka seperti itu dikenal sebagai antarmuka fungsional (setelah Java menambahkan dukungan untuk fungsi lambda).

Misalnya, Java memiliki antarmuka Consumer<Type>yang memiliki accept(Type obj)metode. Mengapa antarmuka ini diperlukan?

Di Java 8, koleksi memiliki forEach()metode yang memungkinkan Anda melakukan beberapa tindakan untuk setiap elemen koleksi . Dan di sini antarmuka fungsional digunakan untuk meneruskan tindakan ke metode.Consumer<T>forEach()

Inilah cara Anda dapat menampilkan semua elemen koleksi :

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Hello", "how's", "life?");

list.forEach( (s) -> System.out.println(s) );
Menampilkan semua elemen koleksi (menggunakan ekspresi lambda)

Kompiler akan mengonversi kode di atas menjadi kode di bawah ini:

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Hello", "how's", "life?");

list.forEach(new Consumer<String>()
{
   public void accept(String s)
   {
      System.out.println(s));
   }
});
Menampilkan semua elemen koleksi (menggunakan kelas anonim)

Versi pertama jelas lebih pendek dari yang kedua. Dan meskipun kode dengan ekspresi lambda sulit dibaca, kode dengan kelas dalam anonim terkadang lebih sulit dibaca.



2. Referensi metode

Namun, kode ekspresi lambda kami dapat ditulis lebih pendek.

Pertama, Anda dapat menghilangkan tanda kurung di sekitar sparameter:

list.forEach( (s) -> System.out.println(s) );
Sebelum
list.forEach( s -> System.out.println(s) );
Setelah

Ini hanya bisa dilakukan jika ada satu parameter . Jika ada beberapa parameter, maka Anda harus menggunakan tanda kurung .

Dan kedua, Anda dapat menulisnya seperti ini:

list.forEach( System.out::println );
Notasi paling kompak

Ini adalah notasi yang sama persis. Perhatikan bahwa tidak ada tanda kurung setelah println.

Di sini kita memiliki kode yang sama — pemanggilan metode:

object::method
x -> object.method(x)

Coba pikirkan: kami ingin melakukan beberapa tindakan untuk setiap elemen koleksi list. Jika aksinya adalah pemanggilan fungsi tunggal (seperti println()), maka masuk akal untuk meneruskan fungsi ke metode sebagai parameter.

Tapi bagaimana kita menjelaskan kepada kompiler bahwa kita ingin meneruskan metode daripada memanggilnya? Untuk melakukan ini, alih-alih menggunakan operator titik, kami menggunakan dua titik dua sebelum nama metode. Titik dua tunggal sudah digunakan untuk menunjukkan operator ternary.

Ini adalah notasi paling sederhana dan paling ringkas.



3. Pembangun

Referensi metode dengan titik dua ganda sangat berguna saat kita bekerja dengan aliran I/O. Anda akan melihat ini nanti.

Sementara itu, mari kita bahas tentang 3 cara populer untuk menyampaikan referensi metode:

Referensi ke metode objek

Untuk meneruskan referensi ke metode suatu objek, Anda perlu menulis sesuatu seperti . Kode ini setara dengan .object::method
x -> object.method(x)

Khusus thisdan supervariabel dapat digunakan sebagai objek.

Referensi ke metode kelas

Untuk meneruskan referensi ke metode statis, Anda perlu menulis sesuatu seperti . Kode ini dikonversi menjadi kode seperticlass::methodx -> class.method(x);

Referensi ke konstruktor

Konstruktor berperilaku serupa dengan metode kelas statis, jadi Anda juga bisa meneruskan referensi ke konstruktor. Begini tampilannya: .class::new

Misalnya, Anda dapat menghindari penghapusan tipe untuk koleksi dan meneruskan toArray()referensi metode ke konstruktor yang akan membuat larik yang diinginkan:toArray(int[]::new);