Pertama kali saya terkena ekspresi Lambda adalah di TypeScript (superset JavaScript), dan itu untuk membuat metode TypeScript di luar metode ini daripada dalam metode ini. Setelah menggunakannya, saya tiba -tiba menyadari bahwa Lambda bukan fitur baru kelas baru JDK8? Jadi saya merasa bahwa saya memeriksa informasi yang relevan dan merekamnya:
1. Parameterisasi perilaku
Singkatnya, parameterisasi perilaku berarti bahwa tubuh fungsi hanya berisi kode umum seperti templat, sementara beberapa logika yang berubah dengan skenario bisnis diteruskan ke fungsi dalam bentuk parameter. Menggunakan parameterisasi perilaku dapat membuat program lebih umum untuk mengatasi kebutuhan perubahan yang sering.
Pertimbangkan skenario bisnis, dengan asumsi bahwa kami perlu memfilter Apple melalui program, pertama -tama kami mendefinisikan entitas Apple:
Kelas Publik Apple {/** Nomor*/Private Long ID;/** Warna*/Warna Warna Privat;/** Berat*/Berat Pribadi Float;/** Asal*/Asal Privat; Public Apple () {} Public Apple (ID Panjang, Warna Warna, Berat Mengambang, Asal String) {this.id = ID; this.color = color; this.weight = weight; atau ini {this.id = this; color = color; thisPermintaan awal pengguna mungkin hanya menyaring apel hijau melalui program, sehingga kami dapat dengan cepat mengimplementasikannya melalui program:
Daftar Statis Publik <PLARE> FilterGreeNapples (Daftar <Plepple> Apel) {Daftar <Plain> FilterApples = ArrayList baru <> (); for (Apple Apple Final: Apel) {if (color.green.equals (apple.getColor ())) {filterapples.add (apple);}} filterapples;Kode ini sederhana dan tidak ada yang perlu dikatakan. Tetapi ketika pengguna perlu menjadi hijau, tampaknya memodifikasi kode itu sederhana, itu tidak lebih dari mengubah green dari kondisi penilaian menjadi merah. Tapi kita perlu mempertimbangkan masalah lain. Jika kondisi perubahan sering berubah, ini dilakukan? Jika itu hanya perubahan warna, maka kita dapat secara langsung membiarkan pengguna lulus dalam kondisi penilaian warna, dan parameter metode penilaian mengubah "set yang akan dinilai dan warna yang akan disaring". Tetapi bagaimana jika pengguna tidak hanya menilai warnanya, tetapi juga ingin menilai berat badan, ukuran, dll.? Apakah Anda pikir kami bisa menambahkan parameter yang berbeda untuk menyelesaikan penilaian? Tapi apakah benar -benar bagus untuk melewati parameter seperti ini? Jika ada lebih banyak kondisi penyaringan dan mode kombinasi menjadi lebih dan lebih kompleks, apakah kita perlu mempertimbangkan semua situasi dan memiliki strategi koping yang sesuai untuk setiap situasi? Pada saat ini, kita dapat parameterisasi perilaku, mengekstrak kondisi penyaringan dan meneruskannya sebagai parameter. Saat ini, kita dapat merangkum antarmuka penilaian:
Antarmuka Publik AppleFilter {/*** Filter Abstrak ** @param apple* @return*/boolean accept (Apple apple);}/*** Encapsulate filter ke antarmuka ** @param apel*@param filter* @return*/Daftar statis public <plfilapplesplesbyAppleFilter (daftar <pley apple> Apple, Applefilter Filter) {list Apple = Apple = Apple Apple, Apple Apple, Apple Apple, Apple, Apple, Apple, Apple, Apple, Apple, Apple, Daftar Apple, Daftar Apple, Daftar Apple, Daftar Apple, Apple, Daftar Apple, Apple, Daftar Apple, Daftar Apple, Daftar Apple, Daftar Apple, Daftar Apple, Daftar Apple, Daftar Apple, Apple. untuk (Apple Apple Final: Apel) {if (filter.accept (apple)) {filterapples.add (apple);}} return filterapples;}Setelah abstraksi perilaku di atas, kita dapat mengatur kondisi filter dalam panggilan spesifik dan meneruskan kondisi sebagai parameter ke dalam metode. Saat ini, kami menggunakan metode kelas dalam anonim:
public static void main (string [] args) {list <plepple> apel = new arraylist <> (); // filter apple list <plaring> filterapples = filterapplesbyapplefilter (apel, applefilter baru () {@Overridepublic boolean Accept (apel apel) {// filter apple red {@overridepublic. apple.getweight ()> 100;}});}Desain ini sering digunakan dalam JDK, seperti java.util.comparator, java.util.concurrent.callable, dll. Saat menggunakan jenis antarmuka ini, kita dapat menggunakan kelas anonim untuk menentukan logika eksekusi spesifik dari fungsi di tempat panggilan tertentu. Namun, dari blok kode di atas, meskipun sangat geek, itu tidak cukup ringkas. Di Java8, kita dapat menyederhanakannya melalui Lambda:
// Filter Apple List <Plekat> filterapples = filterappleSbyapplefilter (apel, (apple apple) -> color.red.equals (apple.getColor ()) && apple.getweight ()> = 100); // () -> xxx () adalah parameter metode, dan xxx adalah implementasi metode yang dimiliki metode.
2. Definisi Ekspresi Lambda
Kita dapat mendefinisikan ekspresi lambda sebagai fungsi anonim yang ringkas dan lumayan. Pertama -tama, kita perlu memperjelas bahwa ekspresi Lambda pada dasarnya adalah suatu fungsi. Meskipun bukan milik kelas tertentu, ia memiliki daftar parameter, tubuh fungsi, tipe pengembalian, dan kemampuan untuk melempar pengecualian; Kedua, itu anonim, dan ekspresi lambda tidak memiliki nama fungsi tertentu; Ekspresi Lambda dapat dilewati seperti parameter, sehingga sangat menyederhanakan penulisan kode. Definisi formatnya adalah sebagai berikut:
Format 1: Daftar Parameter -> Ekspresi
Format 2: Daftar Parameter -> {Koleksi Ekspresi}
Perlu dicatat bahwa ekspresi Lambda menyiratkan kata kunci pengembalian, jadi dalam satu ekspresi, kita tidak perlu secara eksplisit menulis kata kunci pengembalian, tetapi ketika ekspresi adalah kumpulan pernyataan, kita perlu secara eksplisit menambahkan pengembalian dan melampirkan beberapa ekspresi dengan kawat gigi keriting {}. Mari kita lihat beberapa contoh di bawah ini:
// mengembalikan panjang string yang diberikan, secara implisit mengembalikan pernyataan (string s) -> s.length () // selalu mengembalikan metode yang tidak ditagih () () -> 42 // berisi beberapa baris ekspresi, terlampir dalam kawat gigi keriting (int x, int y) -> {int z = x * y; return x + z;}3. Gunakan ekspresi lambda berdasarkan antarmuka fungsional
Penggunaan ekspresi lambda membutuhkan bantuan antarmuka fungsional, yang berarti bahwa hanya ketika antarmuka fungsional muncul, kita dapat menyederhanakannya dengan ekspresi lambda.
Antarmuka fungsional khusus:
Antarmuka fungsional didefinisikan sebagai antarmuka yang hanya memiliki satu metode abstrak. Peningkatan dalam definisi antarmuka JAVA8 adalah untuk memperkenalkan metode default, sehingga kami dapat memberikan implementasi default metode dalam antarmuka. Namun, tidak peduli berapa banyak metode default yang ada, selama satu memiliki dan hanya satu metode abstrak, itu adalah antarmuka fungsional, sebagai berikut (lihat AppleFilter di atas):
/*** Antarmuka Filter Apple*/ @FunctionalInterFacepublic Interface AppleFilter {/*** Kondisi Filter Abstrak ** @param Apple* @return*/boolean accept (Apple Apple);}AppleFilter hanya berisi metode abstrak ACCECT (Apple Apple). Menurut definisi, itu dapat dianggap sebagai antarmuka fungsional. Saat mendefinisikan, kami menambahkan anotasi @FunctionInterface ke antarmuka untuk menandai antarmuka sebagai antarmuka fungsional. Namun, antarmuka ini opsional. Setelah menambahkan antarmuka ini, kompiler membatasi antarmuka hanya memiliki metode abstrak, jika tidak kesalahan akan dilaporkan, sehingga disarankan untuk menambahkan anotasi ini ke antarmuka fungsional.
JDK dilengkapi dengan antarmuka fungsional:
JDK adalah ekspresi lambda dengan antarmuka fungsional yang kaya. Di bawah ini adalah contoh penggunaan predikat <T>, konsumen <T>, fungsi <t, r> masing -masing.
Predikat:
@FunctionInterfacepublic Interface Predicate <T> {/*** mengevaluasi prediksi ini pada argumen yang diberikan. ** @param t argumen input* @return {@code true} Jika argumen input cocok dengan prediksi,* jika tidak {@code false}*/test boolean (t t);}Fungsi predikat mirip dengan AppleFilter di atas. Ini menggunakan kondisi yang kami atur secara eksternal untuk memverifikasi parameter yang masuk dan mengembalikan hasil verifikasi boolean. Berikut ini menggunakan predikat untuk memfilter elemen koleksi daftar:
/**** Daftar @param* @param predikat* @param <t>* @return*/public <t> Daftar <T> Filter (daftar <T> Daftar, predikat <T> predikat) {Daftar <T> newList = new arraylist <t> (); untuk (final t: list) {if (predicate.test (t) {newl.menggunakan:
demo.filter (daftar, (string str) -> null! = str &&! str.isempty ());
Konsumen
@FunctionInterfacepublic Interface Consumer <T> {/*** melakukan operasi ini pada argumen yang diberikan. ** @param t Argumen input*/void accept (t t);}Konsumen memberikan fungsi abstrak yang diterima yang menerima parameter tetapi tidak mengembalikan nilai. Berikut ini menggunakan konsumen untuk melintasi koleksi.
/*** Traversal dari koleksi dan melakukan perilaku khusus ** @param List* @param konsumen* @param <t>*/public <t> void filter (Daftar <T> Daftar, konsumen <T> konsumen) {untuk (final t t: list) {konsumen.accept (t);}}Menggunakan antarmuka fungsional di atas, iterate melalui koleksi string dan cetak string yang tidak kosong:
demo.filter (daftar, (string str) -> {if (stringutils.isnotblank (str)) {System.out.println (str);}});Fungsi
@FunctionInterfacepublic Interface Function <t, r> {/*** menerapkan fungsi ini pada argumen yang diberikan. ** @param t Argumen fungsi*@return Hasil fungsi*/r Apply (t t);}Fungsi melakukan operasi konversi. Inputnya adalah data tipe t dan mengembalikan data tipe R. berikut ini menggunakan fungsi untuk mengonversi set:
PUBLIK <T, R> Daftar <r> Filter (Daftar <T> Daftar, Fungsi <T, R> Fungsi) {Daftar <r> newList = ArrayList baru <r> (); for (final t t: list) {newList.add (function.apply (t));} return newList;}lainnya:
demo.filter (daftar, (string str) -> integer.parseint (str));
Antarmuka fungsional di atas juga menyediakan beberapa implementasi default dari operasi logis. Mari kita bicarakan nanti saat memperkenalkan metode default antarmuka java8 ~
Beberapa hal yang harus diperhatikan selama penggunaan:
Jenis inferensi:
Selama proses pengkodean, kadang -kadang kita mungkin bertanya -tanya antarmuka fungsional mana kode panggilan kita akan cocok. Bahkan, kompiler akan membuat penilaian yang benar berdasarkan parameter, jenis pengembalian, tipe pengecualian (jika ada), dll.
Saat menelepon dengan cara tertentu, jenis parameter dapat dihilangkan beberapa kali, dengan demikian lebih menyederhanakan kode:
// Filter Apple List<Apple> filterApples = filterApplesByAppleFilter(apples,(Apple apple) -> Color.RED.equals(apple.getColor()) && apple.getWeight() >= 100);// In some cases, we can even omit parameter types, and the compiler will correctly judge List<Apple> filterApples = filterApplesByAppleFilter(apples,apple -> Color.red.equals (apple.getColor ()) && apple.getweight ()> = 100);
Variabel lokal
Semua contoh di atas ekspresi lambda kami menggunakan parameter tubuh mereka, kami juga dapat menggunakan variabel lokal di lambda, sebagai berikut
Int Weight = 100; Daftar <Plekat> FilterApples = FilterAppleSbyAppleFilter (Apel, Apple -> color.red.equals (apple.getColor ()) && apple.getweight ()> = bobot);:
Dalam contoh ini, kami menggunakan bobot variabel lokal di lambda. Namun, menggunakan variabel lokal di lambda harus meminta variabel untuk secara eksplisit dinyatakan sebagai final atau pada kenyataannya final. Ini terutama karena variabel lokal disimpan di tumpukan, dan ekspresi lambda dijalankan di utas lain. Ketika tampilan utas mengakses variabel lokal, variabel memiliki kemungkinan diubah atau didaur ulang, sehingga tidak akan ada masalah keamanan utas setelah modifikasi dengan final.
Iv. Kutipan metode
Menggunakan referensi metode dapat membuat kode lebih disederhanakan. Terkadang penyederhanaan ini membuat kode terlihat lebih intuitif. Mari kita lihat contoh:
/* ... hilangkan operasi inisialisasi apel* /// gunakan lambda ekspresi apel.
Metode Referensi Hubungkan Metode Keanggotaan dan Metode itu sendiri melalui ::, yang terutama dibagi menjadi tiga kategori:
Metode statis
(args) -> classname.staticmethod (args)
Konversi ke
ClassName :: StaticMethod
Contoh metode parameter
(args) -> args.instancemethod ()
Konversi ke
Classname :: instanceMethod // classname adalah tipe args
Metode instan eksternal
(args) -> ext.instancemethod (args)
Konversi ke
ext :: instanceMethod (args)
Lihat:
http://www.codeceo.com/article/lambda-of-java-8.html
Di atas adalah ekspresi lambda dari fitur JDK8 baru yang diperkenalkan editor kepada Anda. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!