هي مضمون ڪنهن لاءِ آهي؟
جيڪڏهن توهان انهن مان ڪنهن به قسم جي قابل نه آهيو، توهان شايد هي مضمون بورنگ، غلط، يا عام طور تي توهان جي چانهه جو پيالو نه ڳولي سگهو ٿا. انهي حالت ۾، ٻين شين ڏانهن وڃڻ لاء آزاد محسوس ڪريو، يا، جيڪڏهن توهان مضمون ۾ چڱي طرح ڄاڻو ٿا، مهرباني ڪري تبصرن ۾ تجويز ڏيو ته آئون آرٽيڪل کي بهتر يا اضافي ڪري سگهان ٿو. مواد ڪنهن به علمي قدر جي دعويٰ نٿو ڪري، اڪيلو ڇڏي ڏيو نوانيت. بلڪل برعڪس: مان ڪوشش ڪندس ته انهن شين کي بيان ڪرڻ جي ڪوشش ڪندس جيڪي پيچيده آهن (ڪجهه ماڻهن لاءِ) جيترو ٿي سگهي. اسٽريم API جي وضاحت ڪرڻ لاءِ هڪ درخواست مون کي هن لکڻ لاءِ متاثر ڪيو. مون ان جي باري ۾ سوچيو ۽ فيصلو ڪيو ته منهنجي وهڪري جا ڪجهه مثال ليمبڊا اظهار جي سمجھڻ کان سواءِ سمجھ ۾ نه ايندا. تنهنڪري اسان شروع ڪنداسين lambda اظهار سان. هن مضمون کي سمجهڻ لاء توهان کي ڇا ڄاڻڻ جي ضرورت آهي؟
توھان وڌيڪ پڙھي سگھوٿا ھن Oracle ٽيوٽوريل
۾ ۽ ٻي جاءِ. ان کي سڏيو ويندو آهي " ٽارگيٽ ٽائپنگ ". توھان نالو ڪري سگھوٿا متغيرن کي جيڪو توھان چاھيو - توھان کي استعمال ڪرڻ جي ضرورت نه آھي ساڳيا نالا جيڪي انٽرفيس ۾ بيان ڪيا ويا آھن. جيڪڏهن ڪو به پيٽرولر نه آهي، ته پوء صرف خالي قوس ظاهر ڪريو. جيڪڏهن صرف هڪ پيٽرولر آهي، صرف متغير جو نالو بغير ڪنهن قوس جي ظاهر ڪريو. هاڻي ته اسان پيٽرولر کي سمجھندا آهيون، اهو وقت تي بحث ڪرڻ جو وقت آهي لامبڊا اظهار جي جسم تي. گھڙيل ڪنگڻ جي اندر، توھان ڪوڊ لکندا آھيو جيئن توھان ھڪڙي عام طريقي لاءِ ڪندا. جيڪڏهن توهان جو ڪوڊ هڪ واحد لڪير تي مشتمل آهي، ته پوء توهان مڪمل طور تي گھمڻ واري ڪنگڻ کي ختم ڪري سگهو ٿا (جيئن if-statements ۽ for-loops). جيڪڏهن توهان جو واحد لڪير لامبڊا ڪجهه موٽائي ٿو، توهان کي بيان شامل ڪرڻ جي ضرورت ناهي
- اهو انهن ماڻهن لاءِ آهي جيڪي سمجهن ٿا ته اهي اڳ ۾ ئي جاوا ڪور کي چڱي طرح ڄاڻن ٿا، پر جاوا ۾ ليمبڊا جي اظهار بابت ڪا ڄاڻ ناهي. يا ٿي سگهي ٿو ته انهن لامبڊا جي اظهار بابت ڪجهه ٻڌو آهي، پر تفصيل نه آهي
- اهو انهن ماڻهن لاءِ آهي جن کي ليمبڊا جي اظهار جي هڪ خاص سمجهه آهي، پر اڃا تائين انهن کان ڊڄي ويا آهن ۽ انهن کي استعمال ڪرڻ جي عادي ناهي.
![جاوا ۾ lambda اظهار جي وضاحت. مثالن ۽ ڪمن سان. حصو 1 - 1](https://cdn.codegym.cc/images/article/7c4222bd-fcde-4993-a190-a7ab1836b4d3/800.jpeg)
-
توھان کي سمجھڻ گھرجي اعتراض تي مبني پروگرامنگ (OOP)، يعني:
- طبقن، شيون، ۽ انهن جي وچ ۾ فرق؛
- انٽرفيس، ڪيئن اهي طبقن کان مختلف آهن، ۽ انٽرفيس ۽ طبقن جي وچ ۾ تعلق؛
- طريقن، انهن کي ڪيئن سڏين ٿا، تجريدي طريقا (يعني بغير ڪنهن عمل جي طريقن)، طريقن جا پيرا ميٽر، طريقا دليل ۽ انهن کي ڪيئن پاس ڪجي؛
- تبديلين تائين رسائي، جامد طريقا/متغير، آخري طريقا/متغير؛
- ورثي جي طبقن ۽ انٽرفيس، انٽرفيس جي ڪيترن ئي ورثي.
- جاوا ڪور جو علم: عام قسمون (جنريڪس)، مجموعا (فهرستون)، موضوع.
ٿوري تاريخ
Lambda ايڪسپريس جاوا ۾ فنڪشنل پروگرامنگ کان آيا، ۽ اتي رياضي کان. آمريڪا ۾ ويهين صديءَ جي وچ ڌاري، الونزو چرچ، جنهن کي رياضي ۽ هر قسم جي تجريدي جو تمام گهڻو شوق هو، پرنسٽن يونيورسٽي ۾ ڪم ڪيو. اهو الونزو چرچ هو جنهن لامبڊا حساب ڪتاب ايجاد ڪيو، جيڪو شروعاتي طور تي تجريدي خيالن جو هڪ مجموعو هو جيڪو مڪمل طور تي پروگرامنگ سان لاڳاپيل نه هو. رياضي دان جهڙوڪ ايلن ٽرنگ ۽ جان وون نيومن هڪ ئي وقت پرنسٽن يونيورسٽي ۾ ڪم ڪيو. سڀ ڪجهه گڏ ٿيو: چرچ لامبدا حساب ڪتاب سان گڏ آيو. ٽرنگ پنهنجي تجريدي ڪمپيوٽنگ مشين کي ترقي ڪئي، جيڪا هاڻي "ٽرنگ مشين" جي نالي سان مشهور آهي. ۽ وون نيومن هڪ ڪمپيوٽر آرڪيٽيڪچر جي تجويز ڏني جيڪا جديد ڪمپيوٽرن جو بنياد بڻيل آهي (هاڻي "وون نيومن آرڪيٽيڪچر" سڏيو ويندو آهي). ان وقت، الونزو چرچ جي خيالن کي ايترو مشهور نه ٿيو جيئن سندس ساٿين جي ڪم (خالص رياضي جي شعبي جي استثنا سان). تنهن هوندي به، ٿوري دير کان پوء جان McCarthy (پڻ هڪ پرنسٽن يونيورسٽي گريجوئيٽ ۽، اسان جي ڪهاڻي جي وقت ۾، ٽيڪنالاجي جي Massachusetts انسٽيٽيوٽ جي هڪ ملازم) چرچ جي خيالن ۾ دلچسپي ورتي. 1958 ۾، هن پهرين فنڪشنل پروگرامنگ ٻولي ٺاهي، LISP، انهن خيالن جي بنياد تي. ۽ 58 سالن کان پوءِ، فنڪشنل پروگرامنگ جا خيال جاوا 8 ۾ پکڙجي ويا. اڃا 70 سال به نه گذريا آهن... سچ پڇو ته اهو سڀ کان ڊگهو نه آهي جيڪو رياضياتي خيال کي عملي طور تي لاڳو ڪرڻ لاءِ ورتو ويو آهي.دل جو معاملو
هڪ lambda اظهار هڪ قسم جو فعل آهي. توھان ان کي سمجھي سگھوٿا ھڪڙو عام جاوا طريقو آھي پر مخصوص قابليت سان ٻين طريقن ڏانھن ھڪ دليل جي طور تي. اهو درست آهي. اهو ممڪن ٿي چڪو آهي ته نه رڳو انگن، تارن ۽ ڪيٽس کي طريقن سان، پر ٻين طريقن سان پڻ! جڏهن اسان کي هن جي ضرورت ٿي سگهي ٿي؟ اهو مددگار ثابت ٿيندو، مثال طور، جيڪڏهن اسان چاهيون ٿا ڪجهه ڪال بڪ جو طريقو پاس ڪرڻ. اهو آهي، جيڪڏهن اسان کي گهربل طريقي جي ضرورت آهي ته اسان کي سڏين ٿا ڪنهن ٻئي طريقي کي سڏڻ جي صلاحيت آهي ته اسان ان ڏانهن وڃو. ٻين لفظن ۾، تنهنڪري اسان کي ڪجهه حالتن ۾ هڪ ڪال بڪ پاس ڪرڻ جي صلاحيت آهي ۽ ٻين ۾ هڪ مختلف ڪال بڪ. ۽ انهي ڪري ته اسان جو طريقو جيڪو اسان جي ڪال بڪ وصول ڪري ٿو انهن کي سڏي ٿو. ترتيب ڏيڻ هڪ سادي مثال آهي. فرض ڪريو ته اسان ڪجهه چالاڪ ترتيب ڏيڻ وارو الگورتھم لکي رهيا آهيون جيڪو هن طرح نظر اچي ٿو:public void mySuperSort() {
// We do something here
if(compare(obj1, obj2) > 0)
// And then we do something here
}
بيان ۾ if
، اسان طريقي کي سڏين ٿا compare()
، ٻن شين ۾ گذري وڃڻ جو مقابلو ڪيو وڃي، ۽ اسان ڄاڻڻ چاهيون ٿا ته انهن شين مان ڪهڙي "وڏي" آهي. اسان سمجهون ٿا ته ”وڏي“ وارو اچي ٿو ”گهٽ“ کان اڳ. مان اقتباس ۾ ”وڏو“ رکان ٿو، ڇاڪاڻ ته اسان هڪ آفاقي طريقو لکي رهيا آهيون، جنهن سان معلوم ٿيندو ته ڪيئن نه رڳو وڌندي ترتيب ۾، پر هيٺئين ترتيب ۾ پڻ (هن صورت ۾، ”وڏي“ شئي اصل ۾ ”گهٽ“ شئي هوندي. ، ۽ ان جي برعڪس). اسان جي ترتيب لاءِ مخصوص الورورٿم مقرر ڪرڻ لاءِ، اسان کي ان کي اسان جي mySuperSort()
طريقي ۾ منتقل ڪرڻ لاءِ ڪجهه ميکانيزم جي ضرورت آهي. انهي طريقي سان اسان کي اسان جي طريقي سان "ڪنٽرول" ڪرڻ جي قابل هوندو جڏهن اهو سڏيو ويندو آهي. يقينن، اسان ٻه الڳ طريقا لکي سگهون ٿا - mySuperSortAscend()
۽ mySuperSortDescend()
- ترتيب ڏيڻ لاءِ چڙهڻ ۽ نزول جي ترتيب ۾. يا اسان ڪجھ دليل کي طريقي سان منتقل ڪري سگھون ٿا (مثال طور، هڪ بوليان متغير؛ جيڪڏهن صحيح آهي، پوء ترتيب ڏيڻ جي ترتيب ۾، ۽ جيڪڏهن غلط، پوء هيٺيون ترتيب ۾). پر ڇا جيڪڏهن اسان ڪجهه پيچيدگين کي ترتيب ڏيڻ چاهيون ٿا جهڙوڪ اسٽرنگ صفن جي فهرست؟ اسان جي طريقي کي ڪيئن mySuperSort()
معلوم ٿيندو ته انهن اسٽرنگ صفن کي ڪيئن ترتيب ڏيو؟ سائيز جي لحاظ کان؟ سڀني لفظن جي مجموعي ڊيگهه سان؟ شايد الفابيٽ جي بنياد تي صف ۾ پهرين اسٽرنگ تي ٻڌل آهي؟ ۽ ڇا جيڪڏهن اسان کي ڪجهه حالتن ۾ صفن جي فهرست کي ترتيب ڏيڻ جي ضرورت آهي صف جي سائيز، ۽ ٻين ڪيسن ۾ هر صف ۾ سڀني لفظن جي مجموعي ڊيگهه جي مطابق؟ مون کي اميد آهي ته توهان اڳ ۾ ئي comparators جي باري ۾ ٻڌو آهي ۽ اهو ته ان صورت ۾ اسان کي صرف اسان جي ترتيب ڏيڻ جي طريقي سان هڪ comparator اعتراض ڏانهن رخ ڪندو جيڪو گهربل ترتيب ڏيڻ واري الگورتھم کي بيان ڪري ٿو. ڇاڪاڻ ته معياري sort()
طريقو ساڳيو اصول جي بنياد تي لاڳو ڪيو ويو آهي ، مان پنهنجي مثالن ۾ mySuperSort()
استعمال ڪندس .sort()
String[] array1 = {"Dota", "GTA5", "Halo"};
String[] array2 = {"I", "really", "love", "Java"};
String[] array3 = {"if", "then", "else"};
List<String[]> arrays = new ArrayList<>();
arrays.add(array1);
arrays.add(array2);
arrays.add(array3);
Comparator<;String[]> sortByLength = new Comparator<String[]>() {
@Override
public int compare(String[] o1, String[] o2) {
return o1.length - o2.length;
}
};
Comparator<String[]> sortByCumulativeWordLength = new Comparator<String[]>() {
@Override
public int compare(String[] o1, String[] o2) {
int length1 = 0;
int length2 = 0;
for (String s : o1) {
length1 += s.length();
}
for (String s : o2) {
length2 += s.length();
}
return length1 - length2;
}
};
arrays.sort(sortByLength);
نتيجو:
- Dota GTA5 Halo
- if then else
- I really love Java
هتي هر صف ۾ لفظن جي تعداد جي ترتيب سان ترتيب ڏنل آهن. گهٽ لفظن سان هڪ صف کي "گهٽ" سمجهيو ويندو آهي. انهي ڪري اهو پهريون ڀيرو اچي ٿو. وڌيڪ لفظن سان هڪ صف کي "وڏي" سمجهيو ويندو آهي ۽ آخر ۾ رکيل آهي. جيڪڏهن اسان طريقي سان هڪ مختلف موازنہ پاس ڪريون ٿا sort()
، جهڙوڪ sortByCumulativeWordLength
، پوء اسان هڪ مختلف نتيجو حاصل ڪنداسين:
- if then else
- Dota GTA5 Halo
- I really love Java
ھاڻي آھن arrays کي ترتيب ڏنل آھي اکر جي ڪل تعداد جي حساب سان اکر جي لفظن ۾. پهرين صف ۾، 10 اکر آهن، ٻئي ۾ - 12، ۽ ٽئين ۾ - 15. جيڪڏهن اسان وٽ صرف هڪ واحد موازن آهي، ته پوء اسان کي ان لاء الڳ متغير بيان ڪرڻ جي ضرورت ناهي. ان جي بدران، اسان صرف هڪ گمنام ڪلاس ٺاهي سگهون ٿا صحيح طريقي سان ڪال جي وقت sort()
. ڪجهه هن طرح:
String[] array1 = {"Dota", "GTA5", "Halo"};
String[] array2 = {"I", "really", "love", "Java"};
String[] array3 = {"if", "then", "else"};
List<String[]> arrays = new ArrayList<>();
arrays.add(array1);
arrays.add(array2);
arrays.add(array3);
arrays.sort(new Comparator<String[]>() {
@Override
public int compare(String[] o1, String[] o2) {
return o1.length - o2.length;
}
});
اسان ساڳيو نتيجو حاصل ڪنداسين جيئن پهرين صورت ۾. ٽاسڪ 1. ھن مثال کي وري لکو ته جيئن اُھي صفن کي ترتيب ڏئي ھر اَي ۾ لفظن جي تعداد جي وڌندي ترتيب ۾ نه، پر ھيٺئين ترتيب ۾. اسان اڳ ۾ ئي اهو سڀ ڄاڻون ٿا. اسان ڄاڻون ٿا ته شين کي طريقن سان ڪيئن منتقل ڪجي. ان تي منحصر آهي ته اسان کي هن وقت ڪهڙي ضرورت آهي، اسان مختلف شين کي هڪ طريقي سان منتقل ڪري سگهون ٿا، جيڪو پوء ان طريقي کي سڏيندو جيڪو اسان لاڳو ڪيو آهي. هي سوال پڇي ٿو: دنيا ۾ اسان کي هتي ليمبڊا اظهار جي ضرورت ڇو آهي؟ ڇاڪاڻ ته هڪ لامبڊا اظهار هڪ اعتراض آهي جيڪو بلڪل هڪ طريقو آهي. هڪ "طريقه اعتراض" وانگر. ھڪڙي طريقي سان ھڪڙي شيء ۾ ڀريل آھي. اهو صرف هڪ ٿورڙو اڻڄاتل نحو آهي (پر بعد ۾ وڌيڪ). اچو ته هن ڪوڊ تي هڪ ٻيو نظر وجهون:
arrays.sort(new Comparator<String[]>() {
@Override
public int compare(String[] o1, String[] o2) {
return o1.length - o2.length;
}
});
هتي اسان پنهنجي arrays جي فهرست کي وٺون ٿا ۽ ان جي sort()
طريقي کي سڏين ٿا، جنهن ۾ اسان هڪ واحد compare()
طريقي سان هڪ موازنہ اعتراض پاس ڪريون ٿا (ان جو نالو اسان لاء ڪو به فرق ناهي - آخرڪار، هي اعتراض جو واحد طريقو آهي، تنهنڪري اسان غلط نٿا ٿي سگهون). ھن طريقي ۾ ٻه پيرا ميٽر آھن جن سان اسين ڪم ڪنداسين. جيڪڏهن توهان IntelliJ IDEA ۾ ڪم ڪري رهيا آهيو، توهان شايد ڏٺو آهي ته اهو پيش ڪري ٿو خاص طور تي هيٺ ڏنل ڪوڊ کي ڪنسنس ڪرڻ لاءِ:
arrays.sort((o1, o2) -> o1.length - o2.length);
هي ڇهه سٽون گھٽائي ٿو ھڪڙي ننڍڙي ھڪڙي کي. 6 سٽون هڪ مختصر هڪ جي طور تي ٻيهر لکيا ويا آهن. ڪجھ غائب ٿي ويو، پر مان ضمانت ڏيان ٿو ته اھو ڪجھ به ضروري نه ھو. هي ڪوڊ بلڪل ائين ئي ڪم ڪندو جيئن اهو ڪنهن گمنام طبقي سان ڪندو. ٽاسڪ 2. ٽاسڪ 1 جي حل کي ٻيهر لکڻ تي هڪ اندازو لڳايو هڪ lambda ايڪسپريشن استعمال ڪندي (گهٽ ۾ گهٽ، IntelliJ IDEA کان پڇو ته توهان جي گمنام طبقي کي ليمبڊا ايڪسپريشن ۾ تبديل ڪري).
اچو ته انٽرفيس بابت ڳالهايون
اصول ۾، هڪ انٽرفيس صرف خلاصي طريقن جي هڪ فهرست آهي. جڏهن اسان هڪ ڪلاس ٺاهيندا آهيون جيڪو ڪجهه انٽرفيس کي لاڳو ڪري ٿو، اسان جي ڪلاس کي انٽرفيس ۾ شامل طريقن کي لاڳو ڪرڻ گهرجي (يا اسان کي طبقاتي خلاصو ٺاهڻو پوندو). اتي گھڻن مختلف طريقن سان انٽرفيس آھن (مثال طور،List
)، ۽ صرف ھڪڙي طريقي سان انٽرفيس آھن (مثال طور، Comparator
يا Runnable
). اھڙا انٽرفيس آھن جن وٽ ھڪڙو طريقو ڪونھي (جنھن کي سڏيو ويندو آھي مارڪر انٽرفيس جھڙوڪ Serializable
). انٽرفيس جن ۾ صرف هڪ طريقو هوندو آهي انهن کي فنڪشنل انٽرفيس به چيو ويندو آهي . جاوا 8 ۾، اهي به هڪ خاص تشريح سان نشان لڳل آهن: @FunctionalInterface
. اهو اهي واحد-طريقي انٽرفيس آهن جيڪي ليمبڊا اظهار لاءِ ٽارگيٽ قسم جي طور تي مناسب آهن. جيئن مون مٿي چيو آهي، هڪ لامبڊا اظهار هڪ طريقو آهي جيڪو هڪ اعتراض ۾ لپي ويو آهي. ۽ جڏهن اسان اهڙي شئي کي پاس ڪندا آهيون، اسان لازمي طور تي هي واحد طريقو گذري رهيا آهيون. اهو ظاهر ٿئي ٿو ته اسان کي پرواه ناهي ته طريقو ڇا سڏيو ويندو آهي. صرف شيون جيڪي اسان لاءِ اهميت رکن ٿيون اهي طريقا پيرا ميٽرز آهن ۽ يقيناً، طريقي جو جسم. ذات ۾، هڪ lambda اظهار هڪ فنڪشنل انٽرفيس جو نفاذ آهي. جتي به اسان هڪ انٽرفيس کي هڪ واحد طريقي سان ڏسون ٿا، هڪ گمنام طبقي کي ليمبڊا جي طور تي ٻيهر لکي سگهجي ٿو. جيڪڏهن انٽرفيس ۾ هڪ کان وڌيڪ يا گهٽ طريقو آهي، ته پوءِ هڪ lambda اظهار ڪم نه ڪندو ۽ ان جي بدران اسين هڪ گمنام ڪلاس يا عام طبقي جو هڪ مثال استعمال ڪنداسين. هاڻي اهو وقت آهي ته لمبڊاس ۾ ڪجهه کوٽائي. :)
نحو
عام نحو ڪجهه هن طرح آهي:(parameters) -> {method body}
اهو آهي، طريقي جي پيراگراف جي چوڌاري قوس، هڪ "تير" (هڪ هائيفن ۽ وڏي کان وڌيڪ نشاني سان ٺهيل)، ۽ پوء طريقي جي جسم ۾، هميشه وانگر. پيرا ميٽرز انهن سان ملن ٿا جيڪي انٽرفيس جي طريقي ۾ بيان ڪيل آهن. جيڪڏهن متغير جا قسم واضح طور تي مرتب ڪري سگهجن ٿا (اسان جي صورت ۾، اهو ڄاڻي ٿو ته اسان string arrays سان ڪم ڪري رهيا آهيون، ڇاڪاڻ ته اسان جو List
اعتراض ٽائپ ڪيو ويو آهي String[
])، پوء توهان کي انهن جي قسمن کي ظاهر ڪرڻ جي ضرورت ناهي.
جيڪڏهن اهي مبهم آهن، پوء قسم کي ظاهر ڪريو. IDEA ان کي گرين رنگ ڏيندو جيڪڏهن اها ضرورت نه هجي. |
return
. پر جيڪڏھن توھان گھگھرايل ڪنگڻ استعمال ڪريو ٿا، توھان کي لازمي طور تي ھڪڙو return
بيان شامل ڪرڻ گھرجي، جيئن توھان ھڪڙي عام طريقي سان ڪندا.
مثال
مثال 1.() -> {}
سادو مثال. ۽ سڀ کان وڌيڪ بيڪار :)، ڇاڪاڻ ته اهو ڪجهه به نٿو ڪري. مثال 2.
() -> ""
ٻيو دلچسپ مثال. اهو ڪجھ به نه وٺندو آهي ۽ هڪ خالي تار واپس ڪندو آهي ( return
خارج ڪيو ويو آهي، ڇاڪاڻ ته اهو غير ضروري آهي). هتي ساڳي شيء آهي، پر هن سان return
:
() -> {
return "";
}
مثال 3. "هيلو، دنيا!" lambdas استعمال ڪندي
() -> System.out.println("Hello, World!")
return
اهو ڪجھ به نه وٺندو آهي ۽ ڪجھ به واپس نه ڪندو آهي (اسان ڪال ڪرڻ کان اڳ نٿا رکي سگهون System.out.println()
، ڇاڪاڻ ته println()
طريقي جي واپسي جو قسم آهي void
). اهو صرف سلام ڏيکاري ٿو. اهو انٽرفيس تي عمل ڪرڻ لاء مثالي آهي Runnable
. هيٺ ڏنل مثال وڌيڪ مڪمل آهي:
public class Main {
public static void main(String[] args) {
new Thread(() -> System.out.println("Hello, World!")).start();
}
}
يا هن طرح:
public class Main {
public static void main(String[] args) {
Thread t = new Thread(() -> System.out.println("Hello, World!"));
t.start();
}
}
يا اسان لامبڊا اظهار کي هڪ Runnable
اعتراض جي طور تي محفوظ ڪري سگهون ٿا ۽ پوء ان کي Thread
تعمير ڪندڙ ڏانهن منتقل ڪري سگهون ٿا:
public class Main {
public static void main(String[] args) {
Runnable runnable = () -> System.out.println("Hello, World!");
Thread t = new Thread(runnable);
t.start();
}
}
اچو ته هڪ ويجهي نظر رکون ٿا ان وقت تي جڏهن هڪ لامبڊا ايڪسپريس هڪ متغير ڏانهن محفوظ ڪيو ويو آهي. انٽرفيس Runnable
اسان کي ٻڌائي ٿو ته ان جي شين جو هڪ طريقو هجڻ گهرجي public void run()
. انٽرفيس جي مطابق، run
طريقو ڪو به پيٽرول نه وٺندو آهي. ۽ اهو ڪجھ به نه ٿو ڏئي، يعني ان جي واپسي جو قسم آهي void
. ان جي مطابق، هي ڪوڊ هڪ طريقي سان هڪ اعتراض ٺاهيندو جيڪو ڪجھ به نه وٺي يا واپس نه ٿو ڪري. هي مڪمل طور تي Runnable
انٽرفيس جي run()
طريقي سان ملندو آهي. ان ڪري اسان هن ليمبڊا ايڪسپريس کي Runnable
متغير ۾ رکڻ جي قابل هئاسين. مثال 4.
() -> 42
ٻيهر، اهو ڪجھ به نه وٺندو آهي، پر اهو نمبر 42 واپس ڪري ٿو. اهڙي ليمبڊا ايڪسپريشن کي متغير ۾ رکي سگهجي ٿو Callable
، ڇاڪاڻ ته هن انٽرفيس ۾ صرف هڪ طريقو آهي جيڪو ڪجهه هن طرح نظر اچي ٿو:
V call(),
V
واپسي جو قسم ڪٿي آهي (اسان جي صورت ۾، int
). ان جي مطابق، اسان هيٺ ڏنل لامبڊا اظهار کي محفوظ ڪري سگهون ٿا:
Callable<Integer> c = () -> 42;
مثال 5. هڪ ليمبڊا ايڪسپريشن جنهن ۾ ڪيترائي سٽون شامل آهن
() -> {
String[] helloWorld = {"Hello", "World!"};
System.out.println(helloWorld[0]);
System.out.println(helloWorld[1]);
}
ٻيهر، هي هڪ لامبڊا اظهار آهي جنهن ۾ ڪو به پيٽرول ۽ void
واپسي جو قسم ناهي (ڇاڪاڻ ته ڪو بيان ناهي return
). مثال 6
x -> x
هتي اسان هڪ x
variable وٺي ۽ ان کي واپس. مهرباني ڪري نوٽ ڪريو ته جيڪڏهن هتي صرف هڪ پيٽرولر آهي، ته پوء توهان ان جي چوڌاري قوس کي ختم ڪري سگهو ٿا. هتي ساڳي شيء آهي، پر قوس سان:
(x) -> x
۽ هتي هڪ مثال آهي واضح واپسي واري بيان سان:
x -> {
return x;
}
يا هن وانگر قوس ۽ واپسي واري بيان سان:
(x) -> {
return x;
}
يا قسم جي واضح اشارو سان (۽ اهڙيء طرح قوس سان):
(int x) -> x
مثال 7
x -> ++x
اسان x
ان کي وٺون ٿا ۽ واپس ڪريون ٿا، پر صرف 1 شامل ڪرڻ کان پوء. توھان وري لکي سگھوٿا لامبڊا ھن طرح:
x -> x + 1
ٻنهي صورتن ۾، اسان پيراميٽر ۽ ميٿڊ باڊي جي چوڌاري قوسون ختم ڪريون ٿا، بيان سان گڏ return
، ڇاڪاڻ ته اهي اختياري آهن. نسخن سان قوس ۽ واپسي جو بيان مثال 6 ۾ ڏنو ويو آهي. مثال 8
(x, y) -> x % y
اسان وٺون ٿا x
۽ y
واپس ڏيون ٿا باقي تقسيم جي x
ذريعي y
. پيرا ميٽرن جي چوڌاري قوسون هتي گهربل آهن. اهي صرف اختياري آهن جڏهن صرف هڪ پيٽرولر آهي. هتي ان قسم جي هڪ واضح اشارو سان آهي:
(double x, int y) -> x % y
مثال 9
(Cat cat, String name, int age) -> {
cat.setName(name);
cat.setAge(age);
}
اسان هڪ Cat
اعتراض، هڪ String
نالو، ۽ هڪ عمر وٺون ٿا. پاڻ طريقي ۾، اسان ٻلي تي متغير مقرر ڪرڻ لاء منظور ٿيل نالو ۽ عمر استعمال ڪندا آهيون. ڇاڪاڻ ته اسان جو cat
اعتراض هڪ حوالو جو قسم آهي، اهو لامبڊا اظهار کان ٻاهر تبديل ڪيو ويندو (اهو منظور ٿيل نالو ۽ عمر حاصل ڪندو). ھتي ھڪڙو ٿورڙو وڌيڪ پيچيده نسخو آھي جيڪو ھڪڙي لامبڊا استعمال ڪري ٿو:
public class Main {
public static void main(String[] args) {
// Create a cat and display it to confirm that it is "empty"
Cat myCat = new Cat();
System.out.println(myCat);
// Create a lambda
Settable<Cat> s = (obj, name, age) -> {
obj.setName(name);
obj.setAge(age);
};
// Call a method to which we pass the cat and lambda
changeEntity(myCat, s);
// Display the cat on the screen and see that its state has changed (it has a name and age)
System.out.println(myCat);
}
private static <T extends HasNameAndAge> void changeEntity(T entity, Settable<T> s) {
s.set(entity, "Smokey", 3);
}
}
interface HasNameAndAge {
void setName(String name);
void setAge(int age);
}
interface Settable<C extends HasNameAndAge> {
void set(C entity, String name, int age);
}
class Cat implements HasNameAndAge {
private String name;
private int age;
@Override
public void setName(String name) {
this.name = name;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
نتيجو:
Cat{name='null', age=0}
Cat{name='Smokey', age=3}
جئين توهان ڏسي سگهو ٿا، Cat
اعتراض هڪ رياست هئي، ۽ پوء رياست تبديل ٿي وئي جڏهن اسان ليمبڊا اظهار استعمال ڪيو. Lambda اظهار مڪمل طور تي عام سان گڏ ملن ٿا. ۽ جيڪڏهن اسان کي هڪ ڪلاس ٺاهڻ جي ضرورت آهي Dog
جيڪا پڻ لاڳو ٿئي ٿي HasNameAndAge
، ته پوء اسين ساڳيا آپريشن ڪري سگهون ٿا Dog
طريقي سان main()
ليمبڊا اظهار کي تبديل ڪرڻ کان سواء. ٽاسڪ 3. ھڪڙي فنڪشنل انٽرفيس کي ھڪڙي طريقي سان لکو جيڪو ھڪڙو نمبر وٺي ۽ ھڪڙو بولين قدر واپس ڪري. هڪ اهڙي انٽرفيس جو عمل لکو جيئن هڪ لامبڊا ايڪسپريشن جيڪو واپس اچي ته صحيح هجي جيڪڏهن پاس ڪيل نمبر 13 سان ورهائجي. ٽاسڪ 4. هڪ فنڪشنل انٽرفيس کي اهڙي طريقي سان لکو جيڪو ٻه اسٽرنگ وٺي ۽ هڪ اسٽرنگ به ڏئي. لمبڊا ايڪسپريس جي طور تي اهڙي انٽرفيس جو عمل لکو جيڪو ڊگھي اسٽرنگ کي واپس ڪري. ٽاسڪ 5. ھڪڙي فنڪشنل انٽرفيس کي ھڪڙي طريقي سان لکو جيڪو وٺي ٿو ٽي فلوٽنگ پوائنٽ نمبر: a، b، ۽ c ۽ پڻ ھڪڙو سچل پوائنٽ نمبر ڏئي ٿو. لمبڊا ايڪسپريس جي طور تي اهڙي انٽرفيس جو عمل لکو جيڪو تعصب کي واپس ڏئي. جيڪڏهن توهان وساري ڇڏيو، اهو آهي D = b^2 — 4ac
. ٽاسڪ 6. ٽاسڪ 5 مان فنڪشنل انٽرفيس استعمال ڪندي، هڪ lambda ايڪسپريشن لکو جيڪو نتيجو ڏئي ٿو a * b^c
. جاوا ۾ lambda اظهار جي وضاحت. مثالن ۽ ڪمن سان. حصو 2
GO TO FULL VERSION