CodeGym /జావా బ్లాగ్ /యాదృచ్ఛికంగా /జావాలో లాంబ్డా వ్యక్తీకరణల వివరణ. ఉదాహరణలు మరియు పనులతో. ...
John Squirrels
స్థాయి
San Francisco

జావాలో లాంబ్డా వ్యక్తీకరణల వివరణ. ఉదాహరణలు మరియు పనులతో. 1 వ భాగము

సమూహంలో ప్రచురించబడింది
ఈ వ్యాసం ఎవరి కోసం?
  • ఇది ఇప్పటికే జావా కోర్ గురించి బాగా తెలుసని భావించే వ్యక్తుల కోసం, కానీ జావాలో లాంబ్డా ఎక్స్‌ప్రెషన్‌ల గురించి ఎటువంటి క్లూ లేదు. లేదా లాంబ్డా వ్యక్తీకరణల గురించి వారు ఏదైనా విన్నారు, కానీ వివరాలు లేవు
  • లాంబ్డా ఎక్స్‌ప్రెషన్‌ల గురించి కొంత అవగాహన ఉన్న, కానీ ఇప్పటికీ వాటిని చూసి భయపడి, వాటిని ఉపయోగించడం అలవాటు లేని వ్యక్తుల కోసం ఇది.
జావాలో లాంబ్డా వ్యక్తీకరణల వివరణ.  ఉదాహరణలు మరియు పనులతో.  పార్ట్ 1 - 1మీరు ఈ వర్గాలలో ఒకదానికి సరిపోకపోతే, మీరు ఈ కథనాన్ని బోరింగ్‌గా, లోపభూయిష్టంగా లేదా సాధారణంగా మీ కప్పు టీ కాకపోవచ్చు. ఈ సందర్భంలో, ఇతర విషయాలకు వెళ్లడానికి సంకోచించకండి లేదా, మీరు ఈ అంశంపై బాగా ప్రావీణ్యం కలిగి ఉన్నట్లయితే, దయచేసి నేను కథనాన్ని ఎలా మెరుగుపరచవచ్చు లేదా అనుబంధించవచ్చు అనే దానిపై వ్యాఖ్యలలో సూచనలు చేయండి. మెటీరియల్ ఏ విద్యాసంబంధమైన విలువను కలిగి ఉండదు, కొత్తదనాన్ని విడనాడదు. చాలా విరుద్ధంగా: నేను సంక్లిష్టమైన (కొంతమంది వ్యక్తులకు) వీలైనంత సరళంగా వివరించడానికి ప్రయత్నిస్తాను. స్ట్రీమ్ APIని వివరించమని చేసిన అభ్యర్థన దీన్ని వ్రాయడానికి నన్ను ప్రేరేపించింది. నేను దాని గురించి ఆలోచించాను మరియు లాంబ్డా వ్యక్తీకరణల గురించి అవగాహన లేకుండా నా స్ట్రీమ్ ఉదాహరణలు కొన్ని అర్థం చేసుకోలేవని నిర్ణయించుకున్నాను. కాబట్టి మేము లాంబ్డా వ్యక్తీకరణలతో ప్రారంభిస్తాము. ఈ కథనాన్ని అర్థం చేసుకోవడానికి మీరు ఏమి తెలుసుకోవాలి?
  1. మీరు ఆబ్జెక్ట్-ఓరియెంటెడ్ ప్రోగ్రామింగ్ (OOP)ని అర్థం చేసుకోవాలి, అవి:

    • తరగతులు, వస్తువులు మరియు వాటి మధ్య వ్యత్యాసం;
    • ఇంటర్‌ఫేస్‌లు, అవి తరగతుల నుండి ఎలా భిన్నంగా ఉంటాయి మరియు ఇంటర్‌ఫేస్‌లు మరియు తరగతుల మధ్య సంబంధం;
    • పద్ధతులు, వాటిని ఎలా పిలవాలి, వియుక్త పద్ధతులు (అంటే అమలు లేకుండా పద్ధతులు), పద్ధతి పారామితులు, పద్ధతి వాదనలు మరియు వాటిని ఎలా పాస్ చేయాలి;
    • యాక్సెస్ మాడిఫైయర్స్, స్టాటిక్ మెథడ్స్/వేరియబుల్స్, ఫైనల్ మెథడ్స్/వేరియబుల్స్;
    • తరగతులు మరియు ఇంటర్‌ఫేస్‌ల వారసత్వం, ఇంటర్‌ఫేస్‌ల బహుళ వారసత్వం.
  2. జావా కోర్ నాలెడ్జ్: జెనెరిక్ రకాలు (జెనరిక్స్), సేకరణలు (జాబితాలు), థ్రెడ్‌లు.
సరే, విషయానికి వద్దాం.

ఒక చిన్న చరిత్ర

లాంబ్డా వ్యక్తీకరణలు ఫంక్షనల్ ప్రోగ్రామింగ్ నుండి జావాకి మరియు గణితశాస్త్రం నుండి వచ్చాయి. 20వ శతాబ్దం మధ్యలో యునైటెడ్ స్టేట్స్‌లో, అలోంజో చర్చ్, గణితశాస్త్రం మరియు అన్ని రకాల సంగ్రహణలను చాలా ఇష్టపడేవారు, ప్రిన్స్‌టన్ విశ్వవిద్యాలయంలో పనిచేశారు. లాంబ్డా కాలిక్యులస్‌ను కనుగొన్నది అలోంజో చర్చి, ఇది మొదట్లో ప్రోగ్రామింగ్‌తో పూర్తిగా సంబంధం లేని నైరూప్య ఆలోచనల సమితి. అలాన్ ట్యూరింగ్ మరియు జాన్ వాన్ న్యూమాన్ వంటి గణిత శాస్త్రజ్ఞులు ప్రిన్స్‌టన్ విశ్వవిద్యాలయంలో అదే సమయంలో పనిచేశారు. అంతా కలిసి వచ్చింది: చర్చి లాంబ్డా కాలిక్యులస్‌తో ముందుకు వచ్చింది. ట్యూరింగ్ తన అబ్‌స్ట్రాక్ట్ కంప్యూటింగ్ మెషీన్‌ను అభివృద్ధి చేశాడు, దీనిని ఇప్పుడు "ట్యూరింగ్ మెషిన్" అని పిలుస్తారు. మరియు వాన్ న్యూమాన్ కంప్యూటర్ నిర్మాణాన్ని ప్రతిపాదించాడు, అది ఆధునిక కంప్యూటర్‌లకు (ఇప్పుడు దీనిని "వాన్ న్యూమాన్ ఆర్కిటెక్చర్" అని పిలుస్తారు) ఆధారంగా రూపొందించబడింది. ఆ సమయంలో, అలోంజో చర్చి' అతని ఆలోచనలు అతని సహోద్యోగుల రచనల వలె ప్రసిద్ధి చెందలేదు (స్వచ్ఛమైన గణిత శాస్త్ర రంగాన్ని మినహాయించి). అయితే, కొంతకాలం తర్వాత జాన్ మెక్‌కార్తీ (ప్రిన్స్‌టన్ యూనివర్శిటీ గ్రాడ్యుయేట్ మరియు మా కథ సమయంలో, మసాచుసెట్స్ ఇన్‌స్టిట్యూట్ ఆఫ్ టెక్నాలజీ ఉద్యోగి కూడా) చర్చి ఆలోచనలపై ఆసక్తి కనబరిచాడు. 1958లో, అతను ఆ ఆలోచనల ఆధారంగా మొదటి ఫంక్షనల్ ప్రోగ్రామింగ్ లాంగ్వేజ్, LISPని సృష్టించాడు. మరియు 58 సంవత్సరాల తర్వాత, ఫంక్షనల్ ప్రోగ్రామింగ్ ఆలోచనలు జావా 8లోకి లీక్ అయ్యాయి. 70 సంవత్సరాలు కూడా గడిచిపోలేదు... నిజాయితీగా చెప్పాలంటే, గణిత శాస్త్ర ఆలోచనను ఆచరణలో వర్తింపజేయడానికి ఇది ఎక్కువ సమయం పట్టదు. మసాచుసెట్స్ ఇన్‌స్టిట్యూట్ ఆఫ్ టెక్నాలజీ ఉద్యోగి) చర్చి ఆలోచనలపై ఆసక్తి పెంచుకున్నాడు. 1958లో, అతను ఆ ఆలోచనల ఆధారంగా మొదటి ఫంక్షనల్ ప్రోగ్రామింగ్ లాంగ్వేజ్, LISPని సృష్టించాడు. మరియు 58 సంవత్సరాల తర్వాత, ఫంక్షనల్ ప్రోగ్రామింగ్ ఆలోచనలు జావా 8లోకి లీక్ అయ్యాయి. 70 సంవత్సరాలు కూడా గడిచిపోలేదు... నిజాయితీగా చెప్పాలంటే, గణిత శాస్త్ర ఆలోచనను ఆచరణలో వర్తింపజేయడానికి ఇది ఎక్కువ సమయం పట్టదు. మసాచుసెట్స్ ఇన్‌స్టిట్యూట్ ఆఫ్ టెక్నాలజీ ఉద్యోగి) చర్చి ఆలోచనలపై ఆసక్తి పెంచుకున్నాడు. 1958లో, అతను ఆ ఆలోచనల ఆధారంగా మొదటి ఫంక్షనల్ ప్రోగ్రామింగ్ లాంగ్వేజ్, LISPని సృష్టించాడు. మరియు 58 సంవత్సరాల తర్వాత, ఫంక్షనల్ ప్రోగ్రామింగ్ ఆలోచనలు జావా 8లోకి లీక్ అయ్యాయి. 70 సంవత్సరాలు కూడా గడిచిపోలేదు... నిజాయితీగా చెప్పాలంటే, గణిత శాస్త్ర ఆలోచనను ఆచరణలో వర్తింపజేయడానికి ఇది ఎక్కువ సమయం పట్టదు.

విషయం యొక్క గుండె

లాంబ్డా వ్యక్తీకరణ అనేది ఒక రకమైన ఫంక్షన్. మీరు దీనిని సాధారణ జావా పద్ధతిగా పరిగణించవచ్చు కానీ వాదనగా ఇతర పద్ధతులకు పంపబడే విలక్షణమైన సామర్థ్యంతో. అది నిజమే. సంఖ్యలు, తీగలు మరియు పిల్లులను పద్ధతులకు మాత్రమే కాకుండా, ఇతర పద్ధతులను కూడా పాస్ చేయడం సాధ్యమైంది! మనకు ఇది ఎప్పుడు అవసరం కావచ్చు? ఉదాహరణకు, మేము కొన్ని కాల్‌బ్యాక్ పద్ధతిని పాస్ చేయాలనుకుంటే ఇది సహాయకరంగా ఉంటుంది. అంటే, మనం పిలిచే పద్ధతి అవసరమైతే, మనం దానికి పాస్ చేసే ఇతర పద్ధతిని కాల్ చేయగల సామర్థ్యాన్ని కలిగి ఉంటుంది. మరో మాటలో చెప్పాలంటే, మేము నిర్దిష్ట పరిస్థితులలో ఒక కాల్‌బ్యాక్‌ను పాస్ చేయగల సామర్థ్యాన్ని కలిగి ఉన్నాము మరియు ఇతరులలో వేరే కాల్‌బ్యాక్‌ను పొందగలము. మరియు మా కాల్‌బ్యాక్‌లను స్వీకరించే మా పద్ధతి వారికి కాల్ చేస్తుంది. క్రమబద్ధీకరణ ఒక సాధారణ ఉదాహరణ. మేము ఈ విధంగా కనిపించే కొన్ని తెలివైన సార్టింగ్ అల్గోరిథం వ్రాస్తున్నామని అనుకుందాం:

public void mySuperSort() { 
    // We do something here 
    if(compare(obj1, obj2) > 0) 
    // And then we do something here 
}
ప్రకటనలో if, మేము పద్ధతిని పిలుస్తాము compare(), పోల్చడానికి రెండు వస్తువులను పాస్ చేస్తాము మరియు వీటిలో ఏది "గొప్పది" అని తెలుసుకోవాలనుకుంటున్నాము. "తక్కువ" కంటే ముందు "పెద్దది" వస్తుందని మేము అనుకుంటాము. నేను కోట్స్‌లో "గ్రేటర్" అని ఉంచాను, ఎందుకంటే మేము సార్వత్రిక పద్ధతిని వ్రాస్తున్నాము, అది ఆరోహణ క్రమంలో మాత్రమే కాకుండా, అవరోహణ క్రమంలో కూడా ఎలా క్రమబద్ధీకరించాలో తెలుసు (ఈ సందర్భంలో, "పెద్ద" వస్తువు వాస్తవానికి "తక్కువ" వస్తువు అవుతుంది. , మరియు వైస్ వెర్సా). మా క్రమబద్ధీకరణ కోసం నిర్దిష్ట అల్గారిథమ్‌ను సెట్ చేయడానికి, దానిని మా పద్ధతికి పంపడానికి మాకు కొంత మెకానిజం అవసరం mySuperSort(). ఆ విధంగా మేము మా పద్ధతిని పిలిచినప్పుడు "నియంత్రించగలము". వాస్తవానికి, మేము రెండు వేర్వేరు పద్ధతులను వ్రాయవచ్చు - mySuperSortAscend()మరియుmySuperSortDescend()- ఆరోహణ మరియు అవరోహణ క్రమంలో క్రమబద్ధీకరించడానికి. లేదా మేము పద్ధతికి కొంత వాదనను పంపవచ్చు (ఉదాహరణకు, బూలియన్ వేరియబుల్; నిజమైతే, ఆరోహణ క్రమంలో మరియు తప్పు అయితే, అవరోహణ క్రమంలో). కానీ మేము స్ట్రింగ్ శ్రేణుల జాబితా వంటి సంక్లిష్టమైనదాన్ని క్రమబద్ధీకరించాలనుకుంటే? mySuperSort()ఈ స్ట్రింగ్ శ్రేణులను ఎలా క్రమబద్ధీకరించాలో మా పద్ధతికి ఎలా తెలుస్తుంది? పరిమాణం ద్వారా? అన్ని పదాల సంచిత పొడవు ద్వారా? బహుశా శ్రేణిలోని మొదటి స్ట్రింగ్ ఆధారంగా అక్షరక్రమంలో ఉందా? మరియు మనం శ్రేణుల జాబితాను కొన్ని సందర్భాల్లో శ్రేణి పరిమాణం ద్వారా మరియు ఇతర సందర్భాల్లో ప్రతి శ్రేణిలోని అన్ని పదాల సంచిత పొడవు ద్వారా క్రమబద్ధీకరించాల్సిన అవసరం ఉంటే? మీరు కంపారిటర్‌ల గురించి ఇప్పటికే విన్నారని నేను ఆశిస్తున్నాను మరియు ఈ సందర్భంలో మేము మా సార్టింగ్ పద్ధతికి కావలసిన సార్టింగ్ అల్గారిథమ్‌ను వివరించే కంపారిటర్ ఆబ్జెక్ట్‌ని పంపుతాము. ఎందుకంటే ప్రమాణం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);
ఫలితం:

  1. Dota GTA5 Halo
  2. if then else
  3. I really love Java
ఇక్కడ శ్రేణులు ప్రతి శ్రేణిలోని పదాల సంఖ్యను బట్టి క్రమబద్ధీకరించబడతాయి. తక్కువ పదాలు కలిగిన శ్రేణి "తక్కువ"గా పరిగణించబడుతుంది. అందుకే ముందు వస్తుంది. ఎక్కువ పదాలతో కూడిన శ్రేణి "గొప్పది"గా పరిగణించబడుతుంది మరియు ముగింపులో ఉంచబడుతుంది. మేము పద్ధతికి వేరొక కంపారిటర్‌ను పాస్ చేస్తే sort(), sortByCumulativeWordLength, మేము వేరొక ఫలితాన్ని పొందుతాము:

  1. if then else
  2. Dota GTA5 Halo
  3. I really love Java
ఇప్పుడు శ్రేణులు శ్రేణి పదాలలోని మొత్తం అక్షరాల సంఖ్యతో క్రమబద్ధీకరించబడతాయి. మొదటి శ్రేణిలో, 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; 
    } 
});
ఇక్కడ మేము మా శ్రేణుల జాబితాను తీసుకొని దాని పద్ధతిని పిలుస్తాము sort(), దానికి మేము కంపారిటర్ ఆబ్జెక్ట్‌ను ఒకే పద్ధతితో పాస్ చేస్తాము compare()(దీని పేరు మాకు పట్టింపు లేదు — అన్నింటికంటే, ఇది ఈ వస్తువు యొక్క ఏకైక పద్ధతి, కాబట్టి మనం తప్పు చేయలేము). ఈ పద్ధతిలో మేము పని చేసే రెండు పారామీటర్‌లు ఉన్నాయి. మీరు IntelliJ IDEAలో పని చేస్తున్నట్లయితే, ఈ క్రింది విధంగా కోడ్‌ను గణనీయంగా కుదించడానికి ఇది ఆఫర్ చేయడాన్ని మీరు బహుశా చూడవచ్చు:

arrays.sort((o1, o2) -> o1.length - o2.length);
ఇది ఆరు పంక్తులను ఒకే చిన్నదిగా తగ్గిస్తుంది. 6 పంక్తులు ఒక చిన్నదిగా తిరిగి వ్రాయబడ్డాయి. ఏదో అదృశ్యమైంది, కానీ అది ముఖ్యమైనది కాదని నేను హామీ ఇస్తున్నాను. ఈ కోడ్ అనామక తరగతితో ఎలా పని చేస్తుందో అదే విధంగా పని చేస్తుంది. టాస్క్ 2. లాంబ్డా ఎక్స్‌ప్రెషన్‌ని ఉపయోగించి టాస్క్ 1కి సొల్యూషన్‌ను తిరిగి వ్రాయడం గురించి అంచనా వేయండి (కనీసం, మీ అనామక తరగతిని లాంబ్డా ఎక్స్‌ప్రెషన్‌గా మార్చమని IntelliJ IDEAని అడగండి).

ఇంటర్‌ఫేస్‌ల గురించి మాట్లాడుకుందాం

సూత్రప్రాయంగా, ఇంటర్‌ఫేస్ అనేది కేవలం నైరూప్య పద్ధతుల జాబితా. మేము కొంత ఇంటర్‌ఫేస్‌ను అమలు చేసే తరగతిని సృష్టించినప్పుడు, మా తరగతి తప్పనిసరిగా ఇంటర్‌ఫేస్‌లో చేర్చబడిన పద్ధతులను అమలు చేయాలి (లేదా మేము తరగతిని వియుక్తంగా చేయాలి). అనేక విభిన్న పద్ధతులతో ఇంటర్‌ఫేస్‌లు ఉన్నాయి (ఉదాహరణకు,  List), మరియు ఒకే ఒక పద్ధతితో ఇంటర్‌ఫేస్‌లు ఉన్నాయి (ఉదాహరణకు, Comparatorలేదా Runnable). ఒకే పద్ధతి లేని ఇంటర్‌ఫేస్‌లు ఉన్నాయి (మార్కర్ ఇంటర్‌ఫేస్‌లు అని పిలవబడేవి వంటివి Serializable). ఒకే పద్ధతిని కలిగి ఉన్న ఇంటర్‌ఫేస్‌లను ఫంక్షనల్ ఇంటర్‌ఫేస్‌లు అని కూడా అంటారు . జావా 8లో, అవి ప్రత్యేక ఉల్లేఖనంతో కూడా గుర్తించబడ్డాయి:@FunctionalInterface. లాంబ్డా వ్యక్తీకరణలకు లక్ష్య రకాలుగా సరిపోయే ఈ సింగిల్-మెథడ్ ఇంటర్‌ఫేస్‌లు. నేను పైన చెప్పినట్లుగా, లాంబ్డా వ్యక్తీకరణ అనేది ఒక వస్తువులో చుట్టబడిన పద్ధతి. మరియు అటువంటి వస్తువును మనం పాస్ చేసినప్పుడు, మనం తప్పనిసరిగా ఈ ఒకే పద్ధతిని పాస్ చేస్తున్నాము. పద్దతి అని పిలవబడేది మనం పట్టించుకోనని తేలింది. పద్ధతి పారామితులు మరియు, వాస్తవానికి, పద్ధతి యొక్క శరీరం మాత్రమే మాకు ముఖ్యమైనవి. సారాంశంలో, లాంబ్డా వ్యక్తీకరణ అనేది ఫంక్షనల్ ఇంటర్‌ఫేస్ యొక్క అమలు. ఒకే పద్ధతితో ఇంటర్‌ఫేస్‌ని ఎక్కడ చూసినా, అనామక తరగతి లాంబ్డాగా తిరిగి వ్రాయబడుతుంది. ఇంటర్‌ఫేస్‌లో ఒకటి కంటే ఎక్కువ లేదా అంతకంటే తక్కువ పద్ధతులు ఉంటే, అప్పుడు లాంబ్డా వ్యక్తీకరణ పని చేయదు మరియు బదులుగా మేము అనామక తరగతిని లేదా సాధారణ తరగతి యొక్క ఉదాహరణను కూడా ఉపయోగిస్తాము. ఇప్పుడు లాంబ్డాస్‌లో కొంచెం త్రవ్వడానికి సమయం ఆసన్నమైంది. :)

వాక్యనిర్మాణం

సాధారణ వాక్యనిర్మాణం ఇలా ఉంటుంది:

(parameters) -> {method body}
అంటే, మెథడ్ పారామీటర్‌ల చుట్టూ ఉన్న కుండలీకరణాలు, ఒక "బాణం" (హైఫన్ మరియు గ్రేటర్-దాన్ సైన్ ద్వారా ఏర్పడింది), ఆపై మెథడ్ బాడీని బ్రేస్‌లలో ఎప్పటిలాగే. పారామితులు ఇంటర్ఫేస్ పద్ధతిలో పేర్కొన్న వాటికి అనుగుణంగా ఉంటాయి. కంపైలర్ ద్వారా వేరియబుల్ రకాలను నిస్సందేహంగా నిర్ణయించగలిగితే (మా విషయంలో, మేము స్ట్రింగ్ శ్రేణులతో పని చేస్తున్నామని దానికి తెలుసు, ఎందుకంటే మా Listఆబ్జెక్ట్ ] ఉపయోగించి టైప్ చేయబడింది String[), అప్పుడు మీరు వాటి రకాలను సూచించాల్సిన అవసరం లేదు.
అవి అస్పష్టంగా ఉంటే, రకాన్ని సూచించండి. IDEA అవసరం లేకుంటే బూడిద రంగులో ఉంటుంది.
మీరు ఈ ఒరాకిల్ ట్యుటోరియల్‌లో మరియు ఇతర చోట్ల మరింత చదవవచ్చు . దీనిని " టార్గెట్ టైపింగ్ " అంటారు . మీకు కావలసిన వేరియబుల్స్‌కు మీరు పేరు పెట్టవచ్చు — మీరు ఇంటర్‌ఫేస్‌లో పేర్కొన్న పేర్లనే ఉపయోగించాల్సిన అవసరం లేదు. పారామితులు లేకుంటే, ఖాళీ కుండలీకరణాలను సూచించండి. ఒకే ఒక పరామితి ఉంటే, కుండలీకరణాలు లేకుండా వేరియబుల్ పేరును సూచించండి. ఇప్పుడు మేము పారామితులను అర్థం చేసుకున్నాము, లాంబ్డా వ్యక్తీకరణ యొక్క శరీరాన్ని చర్చించడానికి ఇది సమయం. కర్లీ బ్రేస్‌ల లోపల, మీరు ఒక సాధారణ పద్ధతి కోసం కోడ్ వ్రాస్తారు. మీ కోడ్‌లో ఒకే లైన్ ఉంటే, మీరు కర్లీ బ్రేస్‌లను పూర్తిగా విస్మరించవచ్చు (if-statements మరియు for-loops లాగానే). మీ సింగిల్-లైన్ లాంబ్డా ఏదైనా తిరిగి ఇస్తే, మీరు aని చేర్చాల్సిన అవసరం లేదుreturnప్రకటన. returnకానీ మీరు కర్లీ బ్రేస్‌లను ఉపయోగిస్తే, మీరు ఒక సాధారణ పద్ధతిలో వలె స్పష్టంగా ఒక ప్రకటనను చేర్చాలి .

ఉదాహరణలు

ఉదాహరణ 1.

() -> {}
సరళమైన ఉదాహరణ. మరియు చాలా అర్ధంలేనిది :), ఎందుకంటే ఇది ఏమీ చేయదు. ఉదాహరణ 2.

() -> ""
మరొక ఆసక్తికరమైన ఉదాహరణ. ఇది ఏమీ తీసుకోదు మరియు ఖాళీ స్ట్రింగ్‌ను అందిస్తుంది ( returnవిస్మరించబడింది, ఎందుకంటే ఇది అనవసరం). ఇక్కడ అదే విషయం ఉంది, కానీ దీనితో return:

() -> { 
    return ""; 
}
ఉదాహరణ 3. "హలో, వరల్డ్!" లాంబ్డాస్ ఉపయోగించి

() -> 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వేరియబుల్ తీసుకొని దానిని తిరిగి ఇస్తాము. ఒక పరామితి మాత్రమే ఉన్నట్లయితే, మీరు దాని చుట్టూ ఉన్న కుండలీకరణాలను వదిలివేయవచ్చని దయచేసి గమనించండి. ఇక్కడ అదే విషయం, కానీ కుండలీకరణాలతో:

(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మరియు తిరిగి ఇస్తాము . పారామితుల చుట్టూ ఉన్న కుండలీకరణాలు ఇక్కడ అవసరం. ఒకే పరామితి ఉన్నప్పుడు మాత్రమే అవి ఐచ్ఛికం. ఇక్కడ ఇది రకాల స్పష్టమైన సూచనతో ఉంది: yxy

(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వస్తువు ఒక స్థితిని కలిగి ఉంది మరియు మేము లాంబ్డా వ్యక్తీకరణను ఉపయోగించిన తర్వాత స్థితి మార్చబడింది. లాంబ్డా వ్యక్తీకరణలు జెనరిక్స్‌తో సంపూర్ణంగా మిళితం అవుతాయి. Dogమరియు మేము అమలు చేసే తరగతిని సృష్టించాల్సిన అవసరం ఉన్నట్లయితే ,  లాంబ్డా వ్యక్తీకరణను మార్చకుండా పద్ధతిలో మేము HasNameAndAgeఅదే ఆపరేషన్లను చేయవచ్చు . టాస్క్ 3. సంఖ్యను తీసుకొని బూలియన్ విలువను అందించే పద్ధతితో ఫంక్షనల్ ఇంటర్‌ఫేస్‌ను వ్రాయండి. ఆమోదించబడిన సంఖ్యను 13తో భాగించగలిగితే నిజాన్ని అందించే లాంబ్డా వ్యక్తీకరణ వలె అటువంటి ఇంటర్‌ఫేస్ యొక్క అమలును వ్రాయండి. టాస్క్ 4.Dogmain()రెండు స్ట్రింగ్‌లను తీసుకొని స్ట్రింగ్‌ను తిరిగి ఇచ్చే పద్ధతితో ఫంక్షనల్ ఇంటర్‌ఫేస్‌ను వ్రాయండి. పొడవైన స్ట్రింగ్‌ను అందించే లాంబ్డా ఎక్స్‌ప్రెషన్ వంటి ఇంటర్‌ఫేస్ యొక్క అమలును వ్రాయండి. టాస్క్ 5. మూడు ఫ్లోటింగ్-పాయింట్ నంబర్‌లను తీసుకునే పద్ధతితో ఫంక్షనల్ ఇంటర్‌ఫేస్‌ను వ్రాయండి: a, b మరియు c మరియు ఫ్లోటింగ్ పాయింట్ నంబర్‌ను కూడా అందిస్తుంది. వివక్షను తిరిగి ఇచ్చే లాంబ్డా వ్యక్తీకరణ వలె అటువంటి ఇంటర్‌ఫేస్ యొక్క అమలును వ్రాయండి. మీరు మరచిపోయినట్లయితే, అది D = b^2 — 4ac. టాస్క్ 6. టాస్క్ 5 నుండి ఫంక్షనల్ ఇంటర్‌ఫేస్‌ని ఉపయోగించి, ఫలితాన్ని అందించే లాంబ్డా ఎక్స్‌ప్రెషన్‌ను వ్రాయండి a * b^c. జావాలో లాంబ్డా వ్యక్తీకరణల వివరణ. ఉదాహరణలు మరియు పనులతో. పార్ట్ 2
వ్యాఖ్యలు
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION