1. Kaedah fungsi

Jika antara muka hanya mempunyai satu kaedah , pembolehubah jenis antara muka itu boleh diberikan nilai yang diberikan oleh ungkapan lambda (fungsi lambda). Antara muka sedemikian dikenali sebagai antara muka berfungsi (selepas Java menambah sokongan untuk fungsi lambda).

Sebagai contoh, Java mempunyai Consumer<Type>antara muka, yang mempunyai accept(Type obj)kaedah. Mengapa antara muka ini diperlukan?

Dalam Java 8, koleksi mempunyai kaedah, yangforEach() membolehkan anda melakukan beberapa tindakan untuk setiap elemen koleksi . Dan di sini antara muka berfungsi digunakan untuk menghantar tindakan kepada kaedah.Consumer<T>forEach()

Begini cara anda boleh memaparkan semua elemen koleksi :

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

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

Pengkompil akan menukar kod di atas kepada kod di bawah:

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));
   }
});
Memaparkan semua elemen koleksi (menggunakan kelas tanpa nama)

Versi pertama pasti lebih pendek daripada versi kedua. Dan sementara kod dengan ungkapan lambda sukar dibaca, kod dengan kelas dalaman tanpa nama kadangkala lebih sukar dibaca.



2. Rujukan kaedah

Walau bagaimanapun, kod ungkapan lambda kami boleh ditulis dengan lebih pendek.

Pertama, anda boleh meninggalkan tanda kurung di sekeliling sparameter:

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

Ini hanya boleh dilakukan jika terdapat satu parameter . Jika terdapat berbilang parameter, maka anda mesti menggunakan kurungan .

Dan kedua, anda boleh menulisnya seperti ini:

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

Ini adalah notasi yang sama. Ambil perhatian bahawa tiada kurungan selepas println.

Di sini kita mempunyai kod yang sama - panggilan kaedah:

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

Fikirkanlah: kami ingin melakukan beberapa tindakan untuk setiap elemen koleksi list. Jika tindakan adalah panggilan fungsi tunggal (seperti println()), maka masuk akal untuk menghantar fungsi kepada kaedah sebagai parameter sahaja.

Tetapi bagaimana kita menerangkan kepada pengkompil bahawa kita mahu lulus kaedah daripada memanggilnya? Untuk melakukan ini, bukannya pengendali titik, kami menggunakan dua titik bertindih sebelum nama kaedah. Satu titik bertindih sudah digunakan untuk menunjukkan pengendali ternary.

Ini adalah notasi yang paling mudah dan paling padat.



3. Pembina

Rujukan kaedah dengan titik bertindih berganda sangat berguna apabila kami bekerja dengan aliran I/O. Anda akan melihat ini sedikit kemudian.

Sementara itu, mari kita bincangkan tentang 3 cara popular untuk lulus rujukan kaedah:

Rujukan kepada kaedah sesuatu objek

Untuk menghantar rujukan kepada kaedah objek, anda perlu menulis sesuatu seperti . Kod ini bersamaan dengan .object::method
x -> object.method(x)

Khas thisdan superpembolehubah boleh digunakan sebagai objek.

Rujukan kepada kaedah kelas

Untuk menghantar rujukan kepada kaedah statik, anda perlu menulis sesuatu seperti . Kod ini akan ditukar kepada kod seperticlass::methodx -> class.method(x);

Rujukan kepada pembina

Pembina berkelakuan serupa dengan kaedah kelas statik, jadi anda juga boleh menghantar rujukan kepada pembina. Begini rupanya: .class::new

Sebagai contoh, anda boleh mendapatkan sekitar jenis pemadaman untuk koleksi dan lulus kaedah toArray()rujukan kepada pembina yang akan mencipta tatasusunan yang dikehendaki:toArray(int[]::new);