இந்தக் கட்டுரை யாருக்காக?
- இந்த கட்டுரையின் முதல் பகுதியைப் படிக்கும் நபர்களுக்கானது ;
- தங்களுக்கு ஏற்கனவே ஜாவா கோர் நன்றாகத் தெரியும், ஆனால் ஜாவாவில் லாம்ப்டா வெளிப்பாடுகள் பற்றி எந்தத் தகவலும் இல்லை என்று நினைக்கும் நபர்களுக்கானது. அல்லது லாம்ப்டா வெளிப்பாடுகளைப் பற்றி அவர்கள் ஏதாவது கேள்விப்பட்டிருக்கலாம், ஆனால் விவரங்கள் குறைவாகவே உள்ளன.
- இது லாம்ப்டா வெளிப்பாடுகளைப் பற்றி ஒரு குறிப்பிட்ட புரிதலைக் கொண்டவர்களுக்கானது.
வெளிப்புற மாறிகளுக்கான அணுகல்
இந்த குறியீடு அநாமதேய வகுப்பில் தொகுக்கிறதா?
int counter = 0;
Runnable r = new Runnable() {
@Override
public void run() {
counter++;
}
};
இல்லை. counter
மாறி இருக்க வேண்டும் final
. அல்லது இல்லையென்றால் final
, குறைந்தபட்சம் அதன் மதிப்பை மாற்ற முடியாது. லாம்ப்டா வெளிப்பாடுகளிலும் இதே கொள்கை பொருந்தும். அவர்கள் அறிவிக்கப்பட்ட இடத்திலிருந்து அவர்கள் "பார்க்கக்கூடிய" அனைத்து மாறிகளையும் அணுகலாம். ஆனால் ஒரு லாம்ப்டா அவற்றை மாற்றக்கூடாது (அவற்றிற்கு ஒரு புதிய மதிப்பை ஒதுக்கவும்). இருப்பினும், அநாமதேய வகுப்புகளில் இந்த தடையைத் தவிர்க்க ஒரு வழி உள்ளது. ஒரு குறிப்பு மாறியை உருவாக்கி, பொருளின் உள் நிலையை மாற்றவும். அவ்வாறு செய்யும்போது, மாறி மாறி மாறாது (அதே பொருளைப் புள்ளிகள்) பாதுகாப்பாகக் குறிக்கலாம் final
.
final AtomicInteger counter = new AtomicInteger(0);
Runnable r = new Runnable() {
@Override
public void run() {
counter.incrementAndGet();
}
};
இங்கே நமது counter
மாறி என்பது ஒரு பொருளின் குறிப்பு AtomicInteger
. இந்த பொருளின் நிலையை மாற்ற இந்த incrementAndGet()
முறை பயன்படுத்தப்படுகிறது. நிரல் இயங்கும் போது மாறியின் மதிப்பு மாறாது. இது எப்போதும் ஒரே பொருளை சுட்டிக்காட்டுகிறது, இது இறுதி முக்கிய வார்த்தையுடன் மாறியை அறிவிக்க உதவுகிறது. இங்கே அதே உதாரணங்கள் உள்ளன, ஆனால் லாம்ப்டா வெளிப்பாடுகளுடன்:
int counter = 0;
Runnable r = () -> counter++;
அநாமதேய வகுப்பைக் கொண்ட பதிப்பின் அதே காரணத்திற்காக இது தொகுக்கப்படாது: counter
நிரல் இயங்கும் போது மாறக்கூடாது. ஆனால் நாம் இதை இப்படி செய்தால் எல்லாம் சரியாகிவிடும்:
final AtomicInteger counter = new AtomicInteger(0);
Runnable r = () -> counter.incrementAndGet();
அழைப்பு முறைகளுக்கும் இது பொருந்தும். லாம்ப்டா வெளிப்பாடுகளுக்குள், நீங்கள் அனைத்து "தெரியும்" மாறிகளையும் அணுகுவது மட்டுமல்லாமல், அணுகக்கூடிய எந்த முறைகளையும் அழைக்கலாம்.
public class Main {
public static void main(String[] args) {
Runnable runnable = () -> staticMethod();
new Thread(runnable).start();
}
private static void staticMethod() {
System.out.println("I'm staticMethod(), and someone just called me!");
}
}
தனிப்பட்டது என்றாலும் staticMethod()
, இது முறையின் உள்ளே அணுகக்கூடியது main()
, எனவே இது முறையில் உருவாக்கப்பட்ட லாம்ப்டாவின் உள்ளே இருந்தும் அழைக்கப்படலாம் main
.
லாம்ப்டா வெளிப்பாடு எப்போது செயல்படுத்தப்படுகிறது?
பின்வரும் கேள்வியை நீங்கள் மிகவும் எளிமையாகக் காணலாம், ஆனால் நீங்கள் அதையே கேட்க வேண்டும்: லாம்ப்டா வெளிப்பாட்டிற்குள் உள்ள குறியீடு எப்போது செயல்படுத்தப்படும்? அது எப்போது உருவாக்கப்படுகிறது? அல்லது அது அழைக்கப்படும் போது (இது இன்னும் அறியப்படவில்லை)? இதை சரிபார்க்க மிகவும் எளிதானது.
System.out.println("Program start");
// All sorts of code here
// ...
System.out.println("Before lambda declaration");
Runnable runnable = () -> System.out.println("I'm a lambda!");
System.out.println("After lambda declaration");
// All sorts of other code here
// ...
System.out.println("Before passing the lambda to the thread");
new Thread(runnable).start();
திரை வெளியீடு:
Program start
Before lambda declaration
After lambda declaration
Before passing the lambda to the thread
I'm a lambda!
லாம்ப்டா வெளிப்பாடு கடைசியில் செயல்படுத்தப்பட்டதை நீங்கள் காணலாம், நூல் உருவாக்கப்பட்ட பிறகு மற்றும் நிரலின் செயல்படுத்தல் முறையை அடையும் போது மட்டுமே run()
. அது அறிவிக்கப்படும் போது நிச்சயமாக இல்லை. லாம்ப்டா வெளிப்பாட்டை அறிவிப்பதன் மூலம், ஒரு Runnable
பொருளை மட்டும் உருவாக்கி அதன் run()
முறை எவ்வாறு செயல்படுகிறது என்பதை விவரித்துள்ளோம். முறை மிகவும் பின்னர் செயல்படுத்தப்படுகிறது.
முறை குறிப்புகள்?
முறை குறிப்புகள் லாம்ப்டாக்களுடன் நேரடியாக தொடர்புடையவை அல்ல, ஆனால் இந்த கட்டுரையில் அவற்றைப் பற்றி சில வார்த்தைகளைச் சொல்வது அர்த்தமுள்ளதாக நான் நினைக்கிறேன். எங்களிடம் ஒரு லாம்ப்டா வெளிப்பாடு உள்ளது என்று வைத்துக்கொள்வோம், அது சிறப்பு எதையும் செய்யாது, ஆனால் ஒரு முறையை அழைக்கிறது.
x -> System.out.println(x)
அது சிலவற்றைப் பெறுகிறது x
மற்றும் அழைப்புகளை System.out.println()
அனுப்புகிறது x
. இந்த வழக்கில், விரும்பிய முறையைக் குறிப்பிடுவதன் மூலம் அதை மாற்றலாம். இது போன்ற:
System.out::println
அது சரி — இறுதியில் அடைப்புக்குறிகள் இல்லை! இதோ ஒரு முழுமையான உதாரணம்:
List<String> strings = new LinkedList<>();
strings.add("Dota");
strings.add("GTA5");
strings.add("Halo");
strings.forEach(x -> System.out.println(x));
கடைசி வரியில், forEach()
இடைமுகத்தை செயல்படுத்தும் ஒரு பொருளை எடுக்கும் முறையைப் பயன்படுத்துகிறோம் Consumer
. மீண்டும், இது ஒரு செயல்பாட்டு இடைமுகம், ஒரே ஒரு void accept(T t)
முறை உள்ளது. அதன்படி, ஒரு அளவுருவைக் கொண்ட லாம்ப்டா வெளிப்பாட்டை நாங்கள் எழுதுகிறோம் (இடைமுகத்தில் தட்டச்சு செய்யப்பட்டுள்ளதால், அளவுரு வகையை நாங்கள் குறிப்பிடவில்லை; அதை அழைப்போம் என்று மட்டுமே குறிப்பிடுகிறோம் x
). accept()
லாம்ப்டா வெளிப்பாட்டின் உடலில், முறை அழைக்கப்படும்போது செயல்படுத்தப்படும் குறியீட்டை எழுதுகிறோம் . மாறியில் என்ன முடிந்தது என்பதை இங்கே காண்பிப்போம் x
. இதே forEach()
முறை சேகரிப்பில் உள்ள அனைத்து கூறுகளையும் மீண்டும் செயல்படுத்துகிறது மற்றும் accept()
அதை செயல்படுத்துவதற்கான முறையை அழைக்கிறதுConsumer
இடைமுகம் (எங்கள் லாம்ப்டா), சேகரிப்பில் உள்ள ஒவ்வொரு உருப்படியிலும் கடந்து செல்கிறது. நான் சொன்னது போல், அத்தகைய லாம்ப்டா வெளிப்பாட்டை (வெறுமனே வேறு முறையை வகுப்பது) விரும்பிய முறையைக் குறிப்பிடுவதன் மூலம் மாற்றலாம். பின்னர் எங்கள் குறியீடு இப்படி இருக்கும்:
List<String> strings = new LinkedList<>();
strings.add("Dota");
strings.add("GTA5");
strings.add("Halo");
strings.forEach(System.out::println);
முக்கிய விஷயம் என்னவென்றால், அளவுருக்கள் println()
மற்றும் accept()
முறைகள் பொருந்துகின்றன. லாம்ப்டா வெளிப்பாடுகளுக்குப் பதிலாக, இந்த println()
முறை எதையும் ஏற்றுக்கொள்ளும் (அனைத்து ப்ரிமிட்டிவ் வகைகளுக்கும் அனைத்துப் பொருட்களுக்கும் இது ஓவர்லோட் ஆகும்), நாம் முறைக்கு ஒரு குறிப்பை println()
அனுப்பலாம் forEach()
. பின்னர் forEach()
சேகரிப்பில் உள்ள ஒவ்வொரு உறுப்புகளையும் எடுத்து நேரடியாக முறைக்கு அனுப்பும் println()
. இதை முதன்முறையாக சந்திக்கும் எவருக்கும், நாங்கள் அழைக்கவில்லை என்பதை நினைவில் கொள்ளவும் System.out.println()
(சொற்களுக்கு இடையே புள்ளிகள் மற்றும் இறுதியில் அடைப்புக்குறிகளுடன்). அதற்கு பதிலாக, இந்த முறையைப் பற்றிய குறிப்பை நாங்கள் அனுப்புகிறோம். இதை எழுதினால்
strings.forEach(System.out.println());
தொகுத்தல் பிழை இருக்கும். க்கு அழைப்பதற்கு முன் forEach()
, ஜாவா System.out.println()
அழைக்கப்படுவதைப் பார்க்கிறது, எனவே திரும்பும் மதிப்பு என்பதை அது புரிந்துகொண்டு void
, அதற்குப் பதிலாக ஒரு பொருளை void
எதிர்பார்க்கிறது .forEach()
Consumer
முறை குறிப்புகளுக்கான தொடரியல்
இது மிகவும் எளிமையானது:-
இது போன்ற ஒரு நிலையான முறைக்கான குறிப்பை நாங்கள் அனுப்புகிறோம்:
ClassName::staticMethodName
public class Main { public static void main(String[] args) { List<String> strings = new LinkedList<>(); strings.add("Dota"); strings.add("GTA5"); strings.add("Halo"); strings.forEach(Main::staticMethod); } private static void staticMethod(String s) { // Do something } }
-
ஏற்கனவே உள்ள பொருளைப் பயன்படுத்தி நிலையான முறைக்கு ஒரு குறிப்பை அனுப்புகிறோம், இது போன்றது:
objectName::instanceMethodName
public class Main { public static void main(String[] args) { List<String> strings = new LinkedList<>(); strings.add("Dota"); strings.add("GTA5"); strings.add("Halo"); Main instance = new Main(); strings.forEach(instance::nonStaticMethod); } private void nonStaticMethod(String s) { // Do something } }
-
நிலையற்ற முறையின் குறிப்பைப் பின்வருமாறு செயல்படுத்தும் வகுப்பைப் பயன்படுத்தி அனுப்புகிறோம்:
ClassName::methodName
public class Main { public static void main(String[] args) { List<User> users = new LinkedList<>(); users.add (new User("John")); users.add(new User("Paul")); users.add(new User("George")); users.forEach(User::print); } private static class User { private String name; private User(String name) { this.name = name; } private void print() { System.out.println(name); } } }
-
இது போன்ற ஒரு கட்டமைப்பாளருக்கான குறிப்பை நாங்கள் அனுப்புகிறோம்:
ClassName::new
உங்களிடம் ஏற்கனவே ஒரு முறை இருக்கும் போது முறை குறிப்புகள் மிகவும் வசதியாக இருக்கும். இந்த வழக்கில், முறையின் குறியீட்டைக் கொண்ட லாம்ப்டா வெளிப்பாட்டை எழுதுவதற்குப் பதிலாக அல்லது முறையை அழைக்கும் லாம்ப்டா வெளிப்பாட்டை எழுதுவதற்குப் பதிலாக, அதற்கு ஒரு குறிப்பை அனுப்புவோம். அவ்வளவுதான்.
அநாமதேய வகுப்புகள் மற்றும் லாம்ப்டா வெளிப்பாடுகள் இடையே ஒரு சுவாரஸ்யமான வேறுபாடு
ஒரு அநாமதேய வகுப்பில்,this
முக்கிய சொல் அநாமதேய வகுப்பின் பொருளைக் குறிக்கிறது. ஆனால் லாம்ப்டாவிற்குள் இதைப் பயன்படுத்தினால், கொண்டிருக்கும் வகுப்பின் பொருளை அணுகலாம். நாங்கள் உண்மையில் லாம்ப்டா வெளிப்பாட்டை எழுதிய இடம். லாம்ப்டா வெளிப்பாடுகள் அவை எழுதப்பட்ட வகுப்பின் தனிப்பட்ட முறையில் தொகுக்கப்படுவதால் இது நிகழ்கிறது. இந்த "அம்சத்தை" பயன்படுத்த நான் பரிந்துரைக்கவில்லை, ஏனெனில் இது ஒரு பக்க விளைவைக் கொண்டிருப்பதால் அது செயல்பாட்டு நிரலாக்கத்தின் கொள்கைகளுக்கு முரணானது. இந்த அணுகுமுறை OOP உடன் முற்றிலும் ஒத்துப்போகிறது. ;)
எனது தகவலை நான் எங்கிருந்து பெற்றேன், வேறு என்ன படிக்க வேண்டும்?
- ஆரக்கிளின் அதிகாரப்பூர்வ இணையதளத்தில் டுடோரியல். எடுத்துக்காட்டுகள் உட்பட பல விரிவான தகவல்கள்.
- அதே Oracle டுடோரியலில் முறை குறிப்புகள் பற்றிய அத்தியாயம் .
- நீங்கள் உண்மையிலேயே ஆர்வமாக இருந்தால் விக்கிப்பீடியாவில் நுழையுங்கள் .
GO TO FULL VERSION