Last Updated on March 7, 2023 by RAJENDRAPRASAD
Functional Interface and Lambda expression in java in Hindi – Hello दोस्तों rajhindime.in में आपका स्वागत है |
दोस्तों, पिछले post में आपने Interface changes in Java 8 and 9 जैसे default method, static method, private method इत्यादि के बारे में विस्तार से जाना |
आज के इस पोस्ट Functional Interface and Lambda expression in java in hindi में आप Functional Interface तथा Lambda expression के बारे में विस्तार से जानेंगे जो, java 8 से available है |
शुरुआत हम सबसे पहले Lambda expression से करेंगे और फिर धीरे-धीरे Functional Interface की तरफ बढ़ेंगे |
आइए, सबसे पहले जानें कि Lambda Expression की जरुरत क्यों पड़ी |
Need of Lambda Expression:
दोस्तों, जैसा कि आप जानते हो कि, Java एक Object oriented programming languages है |
Functional programming language के बहुत सारे फायदे हैं, उन सभी benefit को java में miss कर रहे थे क्योकि, java एक OOPs language है न कि functional programming language |
समय के साथ-साथ java people को लगने लगा कि, क्यों न java में कुछ ऐसे changes किए जाए जिससे, हमें java में भी functional programing के benefit मिलने लगे|
फिर उन्होंने java 8 से Lambda Expression को लाया | इस तरह हम कह सकते हैं कि, java में functional programming के features/benefits को enable करने के लिए Lambda Expression concept को लाया गया |
Lambda expression in Java:
यह एक anonymous function है अर्थात, ऐसा function जिसका कोई name न हो |
ऐसा function जिसका न कोई name हो, न return type हो और न ही modifier हो, उसे Lambda Expression कहते हैं |
क्या आप जानतें हैं ? LISP यह पहला ऐसा programming language है जिसने, Lambda Expression को use किया |
Java Lambda Expression Syntax:
(argument-list) -> {method-body}
Lamda expression syntax में कुल तीन components होते हैं :
1. argument-list : यह empty अथवा non-empty हो सकता है |
2. Arrow-token : यह एक symbol (चिन्ह) है जो, hyphen – तथा greater than > को जोड़कर बनाया गया है |
इस तरह java में Lambda expression को -> से दर्शाया जाता है | इसका main कार्य argument-list और method-body को जोड़ना है |
3. method-body : इसके अंदर method के statements को define करते हैं |
आइए, अब एक simple method को Lambda Expression में convert करें |
Example 1: without arguments
Normal method:
public void display(){
System.out.println(“I am learning lamda expression ”);
}
Lambda expression:
() -> {System.out.println(“I am learning lamda expression ”);}
Explanation:
Lambda Expression me बदलने के लिए सबसे पहले हमने public, जो कि modifier है उसे हटाया | उसके बाद void, जो कि return type है उसे हटाया | उसके बाद display, जो कि method name है उसे हटाया |
NOTE:
Lambda Expression में,
a. NO modifier
b. NO return type
c. NO method name
इस तरह हमें,
level 1: () -> {System.out.println(“I am learning lamda expression ”);}
मिला |
चूँकि हमारे method-body में एक ही line है, यहाँ {} की जरुरत नहीं है |
इस तरह हमें,
level2: () -> System.out.println(“I am learning lamda expression ”);
मिला |
NOTE: method-body के अन्दर multiple line की स्थिति में {} जरुरी है परन्तु, अगर एक ही line हो तो {} optional है अर्थात, use कर भी सकते हैं और नहीं भी |
Example 2: with arguments
Normal method:
Public void add(int a, int b)
{
System.out.println(a+b);
}
Lambda expression:
(int a, int b) -> System.out.println(a+b);
Explanation:
Name , return type और name को remove करने के बाद हमें,
Level 1: (int a, int b) -> System.out.println(a+b);
मिला |
यहाँ Lambda Expression में दो arguments है, a और b जो कि int datatype की है |
Lambda Expression में यह क्षमता होती है कि, वह स्थिति के अनुसार data type का अनुमान (guess) लगा ले | यह किस तरह automatically data type को guess करेगा, इसे हम कुछ ही समय में जानेंगे |
इस तरह data type remove करने के बाद हमें,
Level 2: (a,b)-> System.out.println(a+b);
मिला |
Example 3:
Normal method:
Public int square(int n)
{
return n*n;
}
Lambda expression :
n->n*n;
Explanation:
Level 1: (int n)-> {return n*n;}
Data type और {} remove करने के बाद,
Level 2: (n)-> return n*n;
यदि argument में केवल एक ही argument हो तब, parenthesis () optional है |
Level 3: n->return n*n;
यहाँ पर हम return keyword को भी remove कर सकते हैं (क्योंकि compiler n*n को by default return type ही समझता है )
Reason : Lambda Expression में जब भी हम बिना {} का use किए, right side में कुछ भी value लेते हैं तब, compiler उसे returned value ही समझता है |
Level 4: n->n*n;
How to call/invoke lambda expressions:
Lambda Expression को use करने के लिए किसी special concept की जरुरत होती है, उसके बगैर हम Lambda Expression को use नहीं कर सकते |
उस concept का name है, “Functional Interface“
अब तब हमने interface के बारे में बहुत सारी जानकारी हासिल की है, आइए अब जानते हैं कि, यह Functional Interface क्या है, जिसके use के बिना हम कभी भी Lambda Expression का use नहीं कर सकते |
Functional Interface in Java:
वह Interface जिसमे केवल एक ही abstract method हो, उसे by default Functional Interface माना जाता है |
Examples:
1. Runnable – जिसमें केवल run() method है |
2. Callable – जिसमें केवल call() method है |
3. Comparable – जिसमें केवल compareTo() method है |
ध्यान दो, Throwable यह एक class है (न कि Interface), जो Java Exception Hierarchy का root class है |
Functional Interface = Interface with SAM (Single Abstract Method)
चूँकि Java 8 से हम interface में default और static method create कर सकते हैं, इसलिए Functional Interface में भी हम अपने जरुरत के अनुसार कितने भी default और static method define कर सकते है |
परन्तु, शर्त बस इतनी है कि केवल और केवल एक ही abstract method होना चाहिए |
@FunctionalInterface annotation in java:
Java में compiler को explicitly यह बताने के लिए कि दिया गया interface Functional Interface है, @FunctionalInterface annotation को लाया गया |
जैसे ही, किसी भी Interface के ऊपर @FunactionInterface को use किया जाता है, तब compiler सबसे पहले यह check करता है कि, दिए गए interface में केवल एक ही abstract method है या नहीं |
यदि compiler को एक से अधिक abstract method मिलता है , तुरंत वह compile time error देता है | “multiple non-overriding abstract methods found in interface IntefaceName”
अगर एक भी abstract method नहीं मिला तब भी वह compile time error देता है |
Image 1: With @FunctionalInterface
Image 2: Without @FunctionalInterface
Explanation :
ऊपर के image 1 में, हमने दो abstract method declare किया तथा @FunctionalInterface use किया है |
चूँकि Functional interface में एक से अधिक abstract method allowed नहीं है इसलिए, error show कर रहा है |
जबकि image 2 में, ऐसा कोई error नहीं show कर रहा है, क्योकि यहाँ @FunctionalInterface नहीं use किया गया है |
@FunctionalInterface और Inheritance :
Case 1:
यदि कोई child interface, जिसमें एक भी abstract method न हो और वह किसी भी Functional Interface को extends करता है तब, उस स्थिति में child interface by default Functional Interface माना जाता है |
Example 4:
@FunctionalInterface
interface A {
public abstract void m1();
}
@FunctionalInterface
interface B extends A{
}
Explanation:
ऊपर के example 4 में Interface_two (जिसमें एक भी abstract method नहीं है) ने Interface_one (जो कि एक Functional Interface है) को extends किया है |
जिसके कारण interface B को method m1() already available है |
Case 2:
यदि parent interface के अंदर एक ही abstract method हो और same वही abstract method child interface में भी हो तब, उस स्थिति में दोनों ही Interface Functional Interface होते हैं |
Example 5:
@FunctionalInterface
interface A {
public abstract void m1();
}
@FunctionalInterface
interface B extends A{
public abstract void m1();
}
Explanation:
ऊपर के example 5 में दोनों ही interface(parent और child) में same एक ही abstract method है, इसलिए दोनों ही interface Functional Interface हैं |
Case 3:
अगर हम किसी Functional interface को extends करना चाहते हैं, और यह भी चाहते हैं कि child interface भी Functional Interface के तरह ही काम करे, उस स्थिति में child interface में कोई भी abstract method (same method के आलावा ) declare नहीं करना चाहिए |
Example 6:
@FunctionalInterface
interface A {
public abstract void m1();
}
@FunctionalInterface
interface B extends A{
public abstract void m2();
}
Explanation :
ऊपर के example 6 में, interface B, Function Interface नहीं है |
क्योकि यहाँ interface B, interface A को extends कर रहा है, इसलिए interface A का method m1() interface B को by default available है |
साथ ही साथ interface B का अपना भी एक abstract method m2() है |
इस तरह interface B में कुल 2 abstract method हो गए, जो कि Functional Interface में allowed नहीं है |
अब तक आपने Functional interface के बारे में काफी कुछ जाना चलिए, अब जानते हैं कि Functional Interface, Lambda expression में क्या योगदान देता है |
Functional Interface और Lambda Expression:
आइए, सबसे पहले समझे कि java 8 से पहले, lambda expression के बिना हम कैसे interface के किसी method को use करते है |
Program 1:
interface Inter1 {
public void m1();
}
class Demo implements Inter1 {
@Override
public void m1() {
System.out.println("m1 implementation without Lambda Expression");
}
}
public class ProgramWithoutLambdaExpression {
public static void main(String[] args) {
Demo d = new Demo();
d.m1();
}
}
OutPut:
m1 implementation without Lambda Expression
Explanation:
ऊपर program 1 में Interface Inter1 में एक abstract method m1() है |
Class Demo ने interface Inter1 को implements किया है और उस method m1() को override किया है |
Class ProgramWithoutLambdaExpression में, class Demo के object refence variable की सहायता से method m1() को call किया गया है |
आइए अब देखते हैं कि same program को Lambda expression द्वारा कैसे लिखते हैं |
Program 2:
interface Inter1 {
public void m1();
}
public class ProgramWithLambdaExpression {
public static void main(String[] args) {
Inter1 in = () -> System.out.println("m1 implementation using Lambda Expression");
in.m1();
}
}
OutPut:
m1 implementation using Lambda Expression
Explanation:
यहाँ हमने,
public void m1() {
System.out.println("m1 implementation without Lambda Expression");
}
को,
() -> System.out.println("m1 implementation using Lambda Expression");
Lambda expression में बदल दिया |
चूँकि कोई भी parent class/interface अपने child /implementation class के object को hold कर सकता है, इसलिए Interface Inter1 के reference variable in में उस lambda expression को assign कर दिया |
Inter1 in = () -> System.out.println("m1 implementation using Lambda Expression");
उसके बाद
in.m1();
call कर लिया |
ध्यान दो, यहाँ Lambda Expression में जो () argument-list है, वह Interface Inter1 के method m1() को belong करता है क्योंकि, इस पुरे expression को Interface Inter1 के reference variable in में hold किया गया है |
आपने देखा, किस तरह Lambda Expression का use करके, बिना interface का कोई implementation class create किए, interface के method को directly use कर लिया | इस तरह हमारे program में codes की बहुत सारी lines कम हो गई |
NOTE: Lambda expression को hold करना बहुत ही जरुरी है, उसके बिना हम उसे use नहीं कर0 सकते | Lambda expression को केवल Functional Interface के reference variable द्वारा ही hold किया जा सकता है |
Program 3:
interface Inter1 {
abstract void add(int a, int b);
}
public class ProgramWithLambdaExpression {
public static void main(String[] args) {
Inter1 in = (a,b)->System.out.println("sum is : "+(a+b));
in.add(20, 30);
in.add(28, 39);
}
}
OutPut:
sum is : 50
sum is : 67
Explanation :
ऊपर के program 3 में , Lambda expression का argument-list (a,b) Interface Inter1 के method add(int a, int b) को belong करता है |
क्योंकि पूरे expression को Interface Inter1 के reference variable in द्वारा hold किया गया है |
आइए, समझते हैं कि Lambda expression के लिए Functional Interface ही क्यों जरुरी है |
Program 4:
interface Inter1 {
abstract void add(int a, int b);
abstract void sub(int a, int b); // added one more method
}
public class ProgramWithLambdaExpression {
public static void main(String[] args) {
Inter1 in = (a,b)->System.out.println("sum is : "+(a+b));
in.add(20, 30);
in.add(28, 39);
}
}
OutPut:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The target type of this expression must be a functional interface
at com.lambdaPractice.ProgramWithLambdaExpression.main(ProgramWithLambdaExpression.java:11)
Explanation:
ऊपर program 4 में हमने, Interface Inter1 के अंदर एक और method declare कर दिया |
चूँकि अब यहाँ दो abstract method हैं, तो अब यह Functional Interface नहीं है |
जब हमने Lambda Expression में argument-list (a,b) लिखा, तब compiler ने देखा कि इस pure expression को interface Int1 के reference variable in द्वारा hold किया गया है तो, यह (a,b) interface Inter1 के method को ही belong करता है |
परन्तु, ध्यान देनेवाली बात यह है कि यहाँ तो दो method हैं add(int a,int b) और sub(int a,int b)
अब यहाँ compiler confuse हो गया कि वह expression में add(int a, int b) को use करे या फिर sub(int a, int b) को |
इसलिए अंत में compile time error दे दिया “The target type of this expression must be a functional interface” चूँकि Functional Interface में एक ही abstract method होता है तो, compiler को कोई भी confusion नहीं होता | इसलिए Lambda expression के लिए Functional Interface होना ही चाहिए |
Program 5:
interface Inter1 {
abstract int square(int a);
}
public class ProgramWithLambdaExpression {
public static void main(String[] args) {
Inter1 in = n->n*n;
System.out.println("Square of 9 is : "+in.square(9));
System.out.println("Square of 7 is : "+in.square(7));
}
}
OutPut:
Square of 9 is : 81
Square of 7 is : 49
Explanation के लिए Example 3 देखें |
आइए ,अब upper के program में, expression Inter1 in = n->n*n; को अलग-अलग values से replace करके देखें कि यह valid expression होगा या नहीं |
1. Inter1 in = (n)->n*n; –valid expression
Reason: केवल एक argument-list के लिए () optional है |
2. Inter1 in = n->{n*n;} — invalid expression
Reason : जब भी हम { } use करते हैं और function द्वारा कुछ value को return करना चाहते हैं, तब return keyword का use करना compulsory होता है |
3. Inter1 in = n->return n*n; —invalid expression
Reason: जब भी return keyword use करे, { } होना ही चाहिए |
4. Inter1 in = n->{return n*n;} —invalid expression
Reason: Lambda expression हमेशा ; से ही end होना चाहिए |
5. Inter1 in = n->{return n*n}; —-invalid expression
Reason: { } के अंदर सारे statements ; द्वारा end होने चाहिए |
6. Inter1 in = n->{return n*n;}; — valid expression
Points to remember :
1. Lambda expression में कितने भी arguments हो सकते हैं |
2. सिर्फ एक arguments के लिए () optional है |
3. Use किए गए Functional Interface reference variable के आधार पर compiler arguments के datatype को automatically guess कर लेता है |
4. Normal method की तरह ही Lambda Expression-body में कितने भी statements हो सकते हैं |
5. सिर्फ एक statement के case में {} optional है |
6. एक से अधिक statements के case में {} compulsory है |
7. Lambda Expression को hold करना जरुरी है और उसे hold करने के लिए Functional Interface की जरुरत होती है |
8. बिना Functional Interface के, हम Lambda Expression नहीं use कर सकते |
9. Lambda Expression-body में {} के बिना हम return keyword नहीं use कर सकते |
10. अगर हम {} use करते हैं और कुछ value को return करना चाहते हैं, तब return keyword use करना compulsory है |
11. Lambda expression हमेशा ; से ही end होना चाहिए |
12. {} के अंदर भी सारे statements ; द्वारा end होने चाहिए |
Conclusion – आज आपने क्या सीखा
इस post में आपने जाना कि Lambda Expression क्या है, उसे कैसे use करते हैं और Lambda Expression में Functional Interface का क्या योगदान है |
आशा है कि, आपको मेरा यह Blog Functional Interface and Lambda expression in java in hindi, जरूर पसंद आया होगा |
अगर आप इस post से related कोई सवाल पूँछना चाहते हैं अथवा कोई सुझाव देना चाहते हैं तो comment करके जरूर बताएं, मैं उसका reply जरूर दूँगा |
इस post को अपना कीमती समय देने के लिए बहुत बहुत धन्यवाद् | फिर मिलेंगें |
please ,exception handling and multi-threading topics pr bhi blog bnaiye
anyway ,nice explanation .
Thank you Tyagi !
Very soon, I will cover suggested topics.