1. ఇంటర్ఫేస్లు
లాంబ్డా ఫంక్షన్లు ఏమిటో అర్థం చేసుకోవడానికి, మీరు మొదట ఇంటర్ఫేస్లు ఏమిటో అర్థం చేసుకోవాలి. కాబట్టి, ప్రధాన అంశాలను గుర్తుచేసుకుందాం.
ఇంటర్ఫేస్ అనేది తరగతి భావన యొక్క వైవిధ్యం. భారీగా కత్తిరించబడిన తరగతి, చెప్పండి. తరగతి వలె కాకుండా, ఇంటర్ఫేస్ దాని స్వంత వేరియబుల్లను కలిగి ఉండదు (స్టాటిక్ వాటిని మినహాయించి). మీరు ఇంటర్ఫేస్ రకంగా ఉండే వస్తువులను కూడా సృష్టించలేరు:
- మీరు క్లాస్ యొక్క వేరియబుల్స్ డిక్లేర్ చేయలేరు
- మీరు వస్తువులను సృష్టించలేరు
ఉదాహరణ:
interface Runnable
{
void run();
}
ఇంటర్ఫేస్ని ఉపయోగించడం
కాబట్టి ఇంటర్ఫేస్ ఎందుకు అవసరం? ఇంటర్ఫేస్లు వారసత్వంతో మాత్రమే ఉపయోగించబడతాయి. ఒకే ఇంటర్ఫేస్ను వివిధ తరగతుల ద్వారా వారసత్వంగా పొందవచ్చు లేదా కూడా చెప్పినట్లు — తరగతులు ఇంటర్ఫేస్ను అమలు చేస్తాయి .
ఒక తరగతి ఇంటర్ఫేస్ను అమలు చేస్తే, అది ఇంటర్ఫేస్ ద్వారా డిక్లేర్ చేయబడిన కానీ అమలు చేయని పద్ధతులను తప్పనిసరిగా అమలు చేయాలి. ఉదాహరణ:
interface Runnable
{
void run();
}
class Timer implements Runnable
{
void run()
{
System.out.println(LocalTime.now());
}
}
class Calendar implements Runnable
{
void run()
{
var date = LocalDate.now();
System.out.println("Today: " + date.getDayOfWeek());
}
}
తరగతి ఇంటర్ఫేస్ను Timer
అమలు చేస్తుంది Runnable
, కాబట్టి ఇది ఇంటర్ఫేస్లో ఉన్న అన్ని పద్ధతులను దానిలోపల ప్రకటించాలి Runnable
మరియు వాటిని అమలు చేయాలి, అంటే ఒక మెథడ్ బాడీలో కోడ్ని వ్రాయాలి. క్లాస్కి కూడా అదే జరుగుతుంది Calendar
.
కానీ ఇప్పుడు Runnable
వేరియబుల్స్ ఇంటర్ఫేస్ను అమలు చేసే వస్తువులకు సూచనలను నిల్వ చేయగలవు Runnable
.
ఉదాహరణ:
కోడ్ | గమనిక |
---|---|
|
run() క్లాస్లోని పద్ధతిని క్లాస్లోని పద్ధతి Timer అంటారు _ _ _ _ run() Timer run() Calendar |
మీరు ఎల్లప్పుడూ ఏదైనా రకానికి చెందిన వేరియబుల్కు ఆబ్జెక్ట్ రిఫరెన్స్ను కేటాయించవచ్చు, ఆ రకం ఆబ్జెక్ట్ యొక్క పూర్వీకుల తరగతుల్లో ఒకటిగా ఉన్నంత వరకు. Timer
మరియు తరగతుల కోసం Calendar
, అటువంటి రెండు రకాలు ఉన్నాయి: Object
మరియు Runnable
.
మీరు వేరియబుల్కు ఆబ్జెక్ట్ రిఫరెన్స్ను కేటాయించినట్లయితే Object
, మీరు క్లాస్లో డిక్లేర్డ్ చేసిన పద్ధతులకు మాత్రమే కాల్ చేయవచ్చు Object
. మరియు మీరు వేరియబుల్కు ఆబ్జెక్ట్ రిఫరెన్స్ను కేటాయించినట్లయితే Runnable
, మీరు ఆ రకం పద్ధతులను కాల్ చేయవచ్చు Runnable
.
ఉదాహరణ 2:
ArrayList<Runnable> list = new ArrayList<Runnable>();
list.add (new Timer());
list.add (new Calendar());
for (Runnable element: list)
element.run();
ఈ కోడ్ పని చేస్తుంది, ఎందుకంటే Timer
మరియు Calendar
ఆబ్జెక్ట్లు రన్ మెథడ్స్ను కలిగి ఉంటాయి, అవి సరిగ్గా పని చేస్తాయి. కాబట్టి, వారికి కాల్ చేయడం సమస్య కాదు. మేము కేవలం రెండు తరగతులకు రన్() పద్ధతిని జోడించినట్లయితే, మేము వాటిని అంత సులభమైన మార్గంలో పిలవలేము.
ప్రాథమికంగా, Runnable
ఇంటర్ఫేస్ రన్ పద్ధతిని ఉంచడానికి ఒక ప్రదేశంగా మాత్రమే ఉపయోగించబడుతుంది.
2. క్రమబద్ధీకరణ
మరింత ఆచరణాత్మకమైన వాటికి వెళ్దాం. ఉదాహరణకు, తీగలను క్రమబద్ధీకరించడాన్ని చూద్దాం.
స్ట్రింగ్ల సేకరణను అక్షర క్రమంలో క్రమబద్ధీకరించడానికి, జావా అనే గొప్ప పద్ధతి ఉందిCollections.sort(collection);
ఈ స్టాటిక్ పద్ధతి ఆమోదించబడిన సేకరణను క్రమబద్ధీకరిస్తుంది. మరియు క్రమబద్ధీకరించే ప్రక్రియలో, ఎలిమెంట్లను మార్చుకోవాలా వద్దా అని అర్థం చేసుకోవడానికి ఇది దాని మూలకాల యొక్క జత పోలికలను నిర్వహిస్తుంది.
క్రమబద్ధీకరణ సమయంలో, ఈ పోలికలు () పద్ధతిని ఉపయోగించి నిర్వహించబడతాయి compareTo
, అన్ని ప్రామాణిక తరగతులు కలిగి ఉంటాయి: Integer
, String
, ...
పూర్ణాంకం తరగతి యొక్క compareTo() పద్ధతి రెండు సంఖ్యల విలువలను పోలుస్తుంది, అయితే String class యొక్క compareTo() పద్ధతి స్ట్రింగ్ల అక్షర క్రమాన్ని చూస్తుంది.
కాబట్టి సంఖ్యల సేకరణ ఆరోహణ క్రమంలో క్రమబద్ధీకరించబడుతుంది, అయితే స్ట్రింగ్ల సేకరణ అక్షర క్రమంలో క్రమబద్ధీకరించబడుతుంది.
ప్రత్యామ్నాయ సార్టింగ్ అల్గోరిథంలు
కానీ మనం తీగలను అక్షర క్రమంలో కాకుండా వాటి పొడవుతో క్రమబద్ధీకరించాలనుకుంటే? మరియు మనం సంఖ్యలను అవరోహణ క్రమంలో క్రమబద్ధీకరించాలనుకుంటే? ఈ సందర్భంలో మీరు ఏమి చేస్తారు?
అటువంటి పరిస్థితులను నిర్వహించడానికి, తరగతి రెండు పారామితులను కలిగి ఉన్న Collections
మరొక పద్ధతిని కలిగి ఉంది :sort()
Collections.sort(collection, comparator);
కంపారిటర్ అనేది క్రమబద్ధీకరణ సమయంలో సేకరణలోని వస్తువులను ఎలా పోల్చాలో తెలిసిన ప్రత్యేక వస్తువు . కంపారిటర్ అనే పదం కంపారిటర్ అనే ఆంగ్ల పదం నుండి వచ్చింది , ఇది పోలిక నుండి వచ్చింది , దీని అర్థం "పోల్చడం".
కాబట్టి ఈ ప్రత్యేక వస్తువు ఏమిటి?
Comparator
ఇంటర్ఫేస్
బాగా, ఇదంతా చాలా సులభం. sort()
పద్ధతి యొక్క రెండవ పరామితి రకంComparator<T>
ఇక్కడ T అనేది సేకరణలోని మూలకాల రకాన్ని సూచించే రకం పరామితి , మరియు ఒకే పద్ధతిని Comparator
కలిగి ఉండే ఇంటర్ఫేస్int compare(T obj1, T obj2);
మరో మాటలో చెప్పాలంటే, కంపారిటర్ ఆబ్జెక్ట్ అనేది కంపారిటర్ ఇంటర్ఫేస్ను అమలు చేసే ఏదైనా తరగతికి చెందిన ఏదైనా వస్తువు. కంపారిటర్ ఇంటర్ఫేస్ చాలా సరళంగా కనిపిస్తుంది:
public interface Comparator<Type>
{
public int compare(Type obj1, Type obj2);
}
పద్ధతి compare()
దానికి ఆమోదించబడిన రెండు వాదనలను పోల్చింది.
పద్ధతి ప్రతికూల సంఖ్యను అందిస్తే, దాని అర్థం obj1 < obj2
. పద్ధతి సానుకూల సంఖ్యను అందిస్తే, దాని అర్థం obj1 > obj2
. పద్ధతి 0ని తిరిగి ఇస్తే, అంటే obj1 == obj2
.
స్ట్రింగ్లను వాటి పొడవుతో పోల్చే కంపారిటర్ ఆబ్జెక్ట్కి ఉదాహరణ ఇక్కడ ఉంది:
public class StringLengthComparator implements Comparator<String>
{
public int compare (String obj1, String obj2)
{
return obj1.length() – obj2.length();
}
}
స్ట్రింగ్ పొడవులను సరిపోల్చడానికి, ఒక పొడవును మరొక దాని నుండి తీసివేయండి.
స్ట్రింగ్లను పొడవు ద్వారా క్రమబద్ధీకరించే ప్రోగ్రామ్ కోసం పూర్తి కోడ్ ఇలా కనిపిస్తుంది:
public class Solution
{
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Collections.sort(list, new StringLengthComparator());
}
}
class StringLengthComparator implements Comparator<String>
{
public int compare (String obj1, String obj2)
{
return obj1.length() – obj2.length();
}
}
3. వాక్యనిర్మాణ చక్కెర
మీరు ఏమనుకుంటున్నారు, ఈ కోడ్ను మరింత కాంపాక్ట్గా వ్రాయవచ్చా? ప్రాథమికంగా, ఉపయోగకరమైన సమాచారాన్ని కలిగి ఉన్న ఒక లైన్ మాత్రమే ఉంది — obj1.length() - obj2.length();
.
కానీ ఒక పద్ధతి వెలుపల కోడ్ ఉనికిలో లేదు, కాబట్టి మేము ఒక compare()
పద్ధతిని జోడించాల్సి వచ్చింది మరియు పద్ధతిని నిల్వ చేయడానికి మేము కొత్త తరగతిని జోడించాలి — StringLengthComparator
. మరియు మనం వేరియబుల్స్ యొక్క రకాలను కూడా పేర్కొనాలి ... ప్రతిదీ సరిగ్గా ఉన్నట్లు అనిపిస్తుంది.
కానీ ఈ కోడ్ను చిన్నదిగా చేయడానికి మార్గాలు ఉన్నాయి. మేము మీ కోసం కొన్ని సింటాక్టిక్ చక్కెరను కలిగి ఉన్నాము. రెండు స్కూప్లు!
అనామక అంతర్గత తరగతి
మీరు కంపారిటర్ కోడ్ను పద్ధతిలోనే వ్రాయవచ్చు main()
మరియు కంపైలర్ మిగిలిన వాటిని చేస్తుంది. ఉదాహరణ:
public class Solution
{
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Comparator<String> comparator = new Comparator<String>()
{
public int compare (String obj1, String obj2)
{
return obj1.length() – obj2.length();
}
};
Collections.sort(list, comparator);
}
}
Comparator
మీరు క్లాస్ని స్పష్టంగా సృష్టించకుండానే ఇంటర్ఫేస్ని అమలు చేసే వస్తువును సృష్టించవచ్చు ! కంపైలర్ దానిని స్వయంచాలకంగా సృష్టిస్తుంది మరియు దానికి కొంత తాత్కాలిక పేరు ఇస్తుంది. పోల్చి చూద్దాం:
Comparator<String> comparator = new Comparator<String>()
{
public int compare (String obj1, String obj2)
{
return obj1.length() – obj2.length();
}
};
Comparator<String> comparator = new StringLengthComparator();
class StringLengthComparator implements Comparator<String>
{
public int compare (String obj1, String obj2)
{
return obj1.length() – obj2.length();
}
}
రెండు వేర్వేరు సందర్భాలలో ఒకే విధమైన కోడ్ బ్లాక్లను సూచించడానికి ఒకే రంగు ఉపయోగించబడుతుంది. ఆచరణలో తేడాలు చాలా చిన్నవి.
కంపైలర్ కోడ్ యొక్క మొదటి బ్లాక్ను ఎదుర్కొన్నప్పుడు, అది సంబంధిత రెండవ బ్లాక్ కోడ్ను ఉత్పత్తి చేస్తుంది మరియు తరగతికి కొంత యాదృచ్ఛిక పేరును ఇస్తుంది.
4. జావాలో లాంబ్డా వ్యక్తీకరణలు
మీరు మీ కోడ్లో అనామక అంతర్గత తరగతిని ఉపయోగించాలని నిర్ణయించుకున్నారని అనుకుందాం. ఈ సందర్భంలో, మీకు ఇలాంటి కోడ్ బ్లాక్ ఉంటుంది:
Comparator<String> comparator = new Comparator<String>()
{
public int compare (String obj1, String obj2)
{
return obj1.length() – obj2.length();
}
};
ఇక్కడ మనం వేరియబుల్ యొక్క డిక్లరేషన్ను అనామక తరగతిని సృష్టించడంతో కలుపుతాము. కానీ ఈ కోడ్ను చిన్నదిగా చేయడానికి ఒక మార్గం ఉంది. ఉదాహరణకు, ఇలా:
Comparator<String> comparator = (String obj1, String obj2) ->
{
return obj1.length() – obj2.length();
};
సెమికోలన్ అవసరం ఎందుకంటే ఇక్కడ మనకు అవ్యక్త క్లాస్ డిక్లరేషన్ మాత్రమే కాకుండా, వేరియబుల్ సృష్టి కూడా ఉంది.
ఇలాంటి సంజ్ఞామానాన్ని లాంబ్డా వ్యక్తీకరణ అంటారు .
కంపైలర్ మీ కోడ్లో ఇలాంటి సంజ్ఞామానాన్ని ఎదుర్కొంటే, అది కోడ్ యొక్క వెర్బోస్ వెర్షన్ను (అనామక అంతర్గత తరగతితో) ఉత్పత్తి చేస్తుంది.
లాంబ్డా వ్యక్తీకరణను వ్రాసేటప్పుడు, మేము తరగతి పేరును మాత్రమే కాకుండా , పద్ధతి పేరును కూడా వదిలివేసామని గమనించండి .Comparator<String>
int compare()
కంపైల్కు పద్ధతిని నిర్ణయించడంలో సమస్య ఉండదు , ఎందుకంటే లాంబ్డా వ్యక్తీకరణ ఒకే పద్ధతిని కలిగి ఉన్న ఇంటర్ఫేస్ల కోసం మాత్రమే వ్రాయబడుతుంది . మార్గం ద్వారా, ఈ నియమాన్ని అధిగమించడానికి ఒక మార్గం ఉంది, కానీ మీరు OOPని మరింత లోతుగా అధ్యయనం చేయడం ప్రారంభించినప్పుడు దాని గురించి తెలుసుకుంటారు (మేము డిఫాల్ట్ పద్ధతుల గురించి మాట్లాడుతున్నాము).
కోడ్ యొక్క వెర్బోస్ వెర్షన్ను మళ్లీ చూద్దాం, అయితే లాంబ్డా ఎక్స్ప్రెషన్ను వ్రాసేటప్పుడు విస్మరించబడే భాగాన్ని మేము బూడిద రంగులోకి మారుస్తాము:
Comparator<String> comparator = new Comparator<String>()
{
public int compare (String obj1, String obj2)
{
return obj1.length() – obj2.length();
}
};
ముఖ్యమైనవి ఏవీ విస్మరించలేదని తెలుస్తోంది. నిజానికి, Comparator
ఇంటర్ఫేస్లో ఒకే ఒక compare()
పద్ధతి ఉంటే, కంపైలర్ మిగిలిన కోడ్ నుండి బూడిద-అవుట్ కోడ్ను పూర్తిగా పునరుద్ధరించగలదు.
క్రమబద్ధీకరణ
మార్గం ద్వారా, ఇప్పుడు మనం సార్టింగ్ కోడ్ను ఇలా వ్రాయవచ్చు:
Comparator<String> comparator = (String obj1, String obj2) ->
{
return obj1.length() – obj2.length();
};
Collections.sort(list, comparator);
లేదా ఇలా కూడా:
Collections.sort(list, (String obj1, String obj2) ->
{
return obj1.length() – obj2.length();
}
);
మేము వెంటనే వేరియబుల్కు comparator
కేటాయించిన విలువతో వేరియబుల్ని భర్తీ చేసాము comparator
.
రకం అనుమితి
అయితే అంతే కాదు. ఈ ఉదాహరణలలోని కోడ్ను మరింత కాంపాక్ట్గా వ్రాయవచ్చు. మొదట, కంపైలర్ obj1
మరియు obj2
వేరియబుల్స్ అని స్వయంగా నిర్ణయించుకోవచ్చు Strings
. మరియు రెండవది, మీరు మెథడ్ కోడ్లో ఒకే కమాండ్ని కలిగి ఉంటే కర్లీ బ్రేస్లు మరియు రిటర్న్ స్టేట్మెంట్ కూడా విస్మరించబడతాయి.
సంక్షిప్త సంస్కరణ ఇలా ఉంటుంది:
Comparator<String> comparator = (obj1, obj2) ->
obj1.length() – obj2.length();
Collections.sort(list, comparator);
మరియు వేరియబుల్ను ఉపయోగించకుండా comparator
, మేము వెంటనే దాని విలువను ఉపయోగిస్తే, మేము ఈ క్రింది సంస్కరణను పొందుతాము:
Collections.sort(list, (obj1, obj2) -> obj1.length() — obj2.length() );
సరే, దాని గురించి మీరు ఏమనుకుంటున్నారు? నిరుపయోగమైన సమాచారం లేకుండా కేవలం ఒక లైన్ కోడ్ — వేరియబుల్స్ మరియు కోడ్ మాత్రమే. దీన్ని చిన్నదిగా చేయడానికి మార్గం లేదు! లేక ఉందా?
5. ఇది ఎలా పని చేస్తుంది
వాస్తవానికి, కోడ్ను మరింత కాంపాక్ట్గా వ్రాయవచ్చు. కానీ తరువాత దాని గురించి మరింత.
మీరు ఒకే పద్ధతితో ఇంటర్ఫేస్ రకాన్ని ఉపయోగించే లాంబ్డా వ్యక్తీకరణను వ్రాయవచ్చు .
ఉదాహరణకు, కోడ్లో , మీరు లాంబ్డా వ్యక్తీకరణను వ్రాయవచ్చు ఎందుకంటే పద్ధతి యొక్క సంతకం ఇలా ఉంటుంది:Collections.sort(list, (obj1, obj2) -> obj1.length() - obj2.length());
sort()
sort(Collection<T> colls, Comparator<T> comp)
మేము సేకరణను క్రమబద్ధీకరణ పద్ధతికి మొదటి ఆర్గ్యుమెంట్గా పంపినప్పుడు ArrayList<String>
, కంపైలర్ రెండవ ఆర్గ్యుమెంట్ రకం అని గుర్తించగలిగింది . మరియు దీని నుండి, ఈ ఇంటర్ఫేస్ ఒకే పద్ధతిని కలిగి ఉందని నిర్ధారించింది . మిగతావన్నీ సాంకేతికత.Comparator<String>
int compare(String obj1, String obj2)
GO TO FULL VERSION