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