1. Funksional metodlar
Agar interfeys faqat bitta metodga ega bo'lsa, bu turdagi interfeys o'zgaruvchisiga lambda-ibora (lambda-funksiyasi) yordamida qiymat berilishi mumkin. Bunday interfeyslar funksional interfeyslar deb atala boshlandi (Java'ga lambda-funksiyalari qo'shilgandan keyin).
Masalan, Java'da Consumer<Тип> (Consumer == Iste'molchi) interfeysi bor, bu yerda accept(Тип obj) metodiga ega. Bu interfeys nima uchun kerak?
Java 8 versiyasida kolleksiyalarga forEach() metodi qo'shildi, bu har bir element uchun kolleksiyani biron-bir amalni bajarish imkonini beradi. Amalni forEach() metodiga uzatishda funksional interfeys Consumer<T> ishlatiladi.
Mana qanday qilib chiqarish mumkin barcha elementlarni kolleksiyadan ekranga:
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Salom", "qanday", "ishlar?");
list.forEach( (s) -> System.out.println(s) );
Kompilyator bu kodni quyidagi kodga aylantiradi:
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "Salom", "qanday", "ishlar?");
list.forEach(new Consumer<String>()
{
public void accept(String s)
{
System.out.println(s);
}
});
Birinchi yozuv ikkinchisiga qaraganda ancha qisqa. Lambda-iboralari bilan kodni o'qish qiyin bo'lsa-da, anonim ichki klasslar bilan kodni o'qish ba'zan yanada qiyinroq bo'ladi.
2. Metodga havola
Lekin bizning lambda-ibora bilan yozilgan kodimizni yanada qisqartirish mumkin.
Birinchidan, parametr s atrofidagi qavslar olib tashlanishi mumkin:
list.forEach( (s) -> System.out.println(s) );
list.forEach( s -> System.out.println(s) );
Buni faqat parametr bitta bo'lsa qilish mumkin. Agar parametrlar bir nechata bo'lsa, qavslardan foydalanish kerak.
Shuningdek, quyidagicha yozish ham mumkin:
list.forEach( System.out::println );
Bu bir xil yozuvdir. E'tibor bering, printlndan keyin qavs yo'q.
Bu yerda yozilgan bir xil kod — metodni chaqirish:
obyekt::metod
x -> obyekt.metod(x)
O'zingiz o'ylang: biz har bir element uchun list kolleksiyasidan biror amal bajarishni xohladik. Agar bu amal — bitta funktsiyani chaqirish bo'lsa (masalan, println()), unda funktsiyani metodga parametr sifatida uzatishni mantiqiyroq bo'lardi.
Komplayatorga funktsiyani chaqirish kerakligini emas, uzatish kerakligini qanday tushuntirish mumkin? Buning uchun metodning nomidan oldin nuqta emas, ikki nuqta qo'yiladi: bitta nuqta ternar operatorida band qilingan.
Bu eng oddiy va ixcham yozuvdir.
3. Konstruktor
Ikki nuqta orqali metodlarga havolalarni ishlatish juda qulay, ayniqsa kiritish-chiqarish oqimlari bilan ish ko'rganda. Bunga keyinroq amin bo'lasiz.
Hozirda metodga havola berishning 3 ta mashhur usulini ko'rib chiqamiz:
Obyekt metodiga havola
Obyekt metodiga havola berish uchun, obyekt::metod shaklida kod yozilishi kerak.
Bu kod x -> obyekt.metod(x) kodiga teng.
Obyekt sifatida this va super kabi maxsus o'zgaruvchilar ishlatilishi mumkin.
Klass metodiga havola
Statik metodga havola berish uchun, klass::metod shaklida kod yozilishi kerak. Bu kod x -> klass.metod(x); kodiga aylantiriladi.
Konstruktor havolasi
Konstruktor o'z ishiga ko'ra klassning statik metodiga o'xshaydi, shuning uchun unga ham havola berish mumkin. Bu klass::new shaklida bo'ladi.
Masalan, kolleksiyalardagi turli turlarni yo'q qilish va metodga toArray() kerakli massivni yaratadigan konstruktor havolasini berish mumkin: toArray(int[]::new );
GO TO FULL VERSION