क्या लैम्बडा एक्सप्रेशंस का कोड की बचत लाइनों के अलावा कोई उपयोग है?


120

क्या लैम्बडा एक्सप्रेशंस का कोड की बचत लाइनों के अलावा कोई उपयोग है?

क्या लैम्ब्डा द्वारा प्रदान की गई कोई विशेष विशेषताएं हैं जो समस्याओं को हल करती हैं जिन्हें हल करना आसान नहीं था? मैंने जो विशिष्ट उपयोग देखा है, वह यह है कि इसे लिखने के बजाय:

Comparator<Developer> byName = new Comparator<Developer>() {
  @Override
  public int compare(Developer o1, Developer o2) {
    return o1.getName().compareTo(o2.getName());
  }
};

हम कोड को छोटा करने के लिए एक लंबोदर अभिव्यक्ति का उपयोग कर सकते हैं:

Comparator<Developer> byName =
(Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName());

27
ध्यान दें कि यह और भी छोटा हो सकता है: (o1, o2) -> o1.getName().compareTo(o2.getName())
Thorbjørn Ravn Andersen

88
या अभी भी छोटा:Comparator.comparing(Developer::getName)
थॉमस क्लैगर

31
मैं उस लाभ को कम नहीं समझूंगा। जब चीजें बहुत आसान होती हैं, तो आप चीजों को "सही" तरीके से करने की अधिक संभावना रखते हैं। लेखन कोड करने के बीच अक्सर कुछ तनाव होता है जो लंबी अवधि में अधिक बनाए रखने के लिए होता है, बनाम अल्पावधि में संक्षेप में आसान। लैम्ब्डा उस तनाव को कम करते हैं, और इसलिए आपको क्लीनर कोड लिखने में मदद करते हैं।
यशवित

5
लैम्ब्डा क्लोज़र हैं, जो अंतरिक्ष की बचत को और अधिक बड़ा बना देता है, क्योंकि अब आपको अपने प्रतिस्थापन वर्ग में एक पैरामीटर वाले कंस्ट्रक्टर, फ़ील्ड, असाइनमेंट कोड आदि को जोड़ने की आवश्यकता नहीं है।
कोडइन्चोसोस

जवाबों:


116

लैम्ब्डा अभिव्यक्तियाँ उन समस्याओं के सेट को नहीं बदलती हैं जिन्हें आप सामान्य रूप से जावा के साथ हल कर सकते हैं, लेकिन निश्चित रूप से कुछ समस्याओं को हल करना आसान बनाते हैं, बस इसी कारण से हम असेंबली भाषा में प्रोग्रामिंग नहीं कर रहे हैं। प्रोग्रामर के काम से अनावश्यक कार्यों को हटाने से जीवन आसान हो जाता है और उन चीजों को करने की अनुमति देता है जिन्हें आप अन्यथा स्पर्श भी नहीं करेंगे, बस आपको कोड की मात्रा (मैन्युअल रूप से) का उत्पादन करना होगा।

लेकिन लैम्ब्डा एक्सप्रेशन सिर्फ कोड की लाइनें नहीं बचा रहे हैं। लैम्ब्डा अभिव्यक्तियाँ आपको कार्यों को परिभाषित करने की अनुमति देती हैं , कुछ ऐसा जिसके लिए आप पहले इनर क्लासेज को वर्कअराउंड के रूप में उपयोग कर सकते हैं, इसीलिए आप इन मामलों में अनाम इनर क्लासेस को बदल सकते हैं, लेकिन सामान्य रूप से नहीं।

सबसे विशेष रूप से, लंबोदर अभिव्यक्तियों को स्वतंत्र रूप से कार्यात्मक इंटरफ़ेस में परिभाषित किया गया है जिसे वे परिवर्तित कर देंगे, इसलिए कोई विरासत में सदस्य नहीं हैं जो वे एक्सेस कर सकते हैं, आगे, वे कार्यात्मक इंटरफ़ेस को लागू करने के प्रकार के उदाहरण तक पहुंच नहीं सकते हैं। एक लंबोदर अभिव्यक्ति के भीतर, thisऔर superआसपास के संदर्भ के रूप में एक ही अर्थ है, यह उत्तर भी देखें । इसके अलावा, आप आसपास के संदर्भ के स्थानीय चर को छायांकित करते हुए नए स्थानीय चर नहीं बना सकते हैं। किसी फ़ंक्शन को परिभाषित करने के इच्छित कार्य के लिए, यह बहुत सारे त्रुटि स्रोतों को हटा देता है, लेकिन इसका अर्थ यह भी है कि अन्य उपयोग के मामलों के लिए, अनाम आंतरिक वर्ग हो सकते हैं जो एक लंबर एक्सप्रेशन में परिवर्तित नहीं हो सकते हैं, भले ही एक कार्यात्मक इंटरफ़ेस लागू करना हो।

इसके अलावा, निर्माण new Type() { … }एक नए विशिष्ट उदाहरण का उत्पादन करने की गारंटी देता है (जैसा कि newहमेशा होता है)। अनाम आंतरिक श्रेणी के उदाहरण हमेशा गैर- staticसंदर्भ में बनाए जाने पर उनके बाहरी उदाहरण का संदर्भ रखते हैं। इसके विपरीत, लैम्ब्डा भाव केवल thisजरूरत पड़ने पर एक संदर्भ को कैप्चर करते हैं, अर्थात यदि वे पहुंचते हैं thisया गैर- staticसदस्य होते हैं। और वे जानबूझकर अनिर्दिष्ट पहचान के उदाहरणों का उत्पादन करते हैं, जो कार्यान्वयन को रनटाइम पर निर्णय लेने की अनुमति देता है कि क्या मौजूदा उदाहरणों का पुन: उपयोग करना है (यह भी देखें कि क्या " लैम्ब्डा अभिव्यक्ति हर बार निष्पादित होने पर ढेर पर ऑब्जेक्ट बनाता है? ")।

ये अंतर आपके उदाहरण पर लागू होते हैं। आपका अनाम आंतरिक वर्ग निर्माण हमेशा एक नया उदाहरण प्रस्तुत करेगा, साथ ही यह बाहरी उदाहरण के संदर्भ को भी कैप्चर कर सकता है, जबकि आपकी (Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName())गैर-कैप्चरिंग लैम्ब्डा अभिव्यक्ति है जो विशिष्ट कार्यान्वयन में एक सिंगलटन का मूल्यांकन करेगी। इसके अलावा, यह .classआपकी हार्ड ड्राइव पर एक फ़ाइल का उत्पादन नहीं करता है ।

दोनों, सिमेंटिक और प्रदर्शन के बारे में मतभेदों को देखते हुए, लैम्ब्डा के भावों में बदलाव हो सकता है जिस तरह से प्रोग्रामर भविष्य में कुछ समस्याओं को हल करेंगे, निश्चित रूप से नए APIs के कारण कार्यात्मक प्रोग्रामिंग के विचारों को नई भाषा सुविधाओं का उपयोग करते हुए। जावा 8 लैम्ब्डा अभिव्यक्ति और प्रथम श्रेणी के मूल्यों को भी देखें ।


1
अनिवार्य रूप से, लैम्ब्डा अभिव्यक्ति एक प्रकार की कार्यात्मक प्रोग्रामिंग है। यह देखते हुए कि किसी भी कार्य को कार्यात्मक प्रोग्रामिंग या अनिवार्य प्रोग्रामिंग के साथ किया जा सकता है , पठनीयता और बनाए रखने के अलावा कोई फायदा नहीं है , जो अन्य चिंताओं को दूर कर सकता है।
ड्रैक 18s अब

1
@ सूचना: आप फ़ंक्शन की परिभाषा के साथ पूरी किताबें भर सकते हैं । आपको यह भी तय करना होगा कि लक्ष्य पर ध्यान केंद्रित करना है या जावा के लैम्ब्डा अभिव्यक्तियों द्वारा समर्थित पहलुओं पर। मेरे उत्तर की अंतिम कड़ी ( यह एक ) पहले से ही जावा के संदर्भ में इनमें से कुछ पहलुओं पर चर्चा करती है। लेकिन मेरे जवाब को समझने के लिए, यह समझना पहले से ही पर्याप्त है कि फ़ंक्शन कक्षाओं की तुलना में एक अलग अवधारणा हैं। अधिक जानकारी के लिए, पहले से ही मौजूद संसाधन और प्रश्नोत्तर हैं ...
होल्गर

1
@ कथन: दोनों कार्य, अधिक समस्याओं को हल करने की अनुमति नहीं देते हैं, जब तक कि आप अन्य समाधानों के लिए कोड आकार / जटिलता या वर्कअराउंड की मात्रा को अस्वीकार्य नहीं मानते हैं (जैसा कि पहले पैराग्राफ में कहा गया है), और पहले से ही कार्यों को परिभाषित करने का एक तरीका था। , जैसा कि कहा गया है, कार्यों को परिभाषित करने के बेहतर तरीके की अनुपस्थिति के लिए आंतरिक कक्षाओं का उपयोग वर्कअराउंड के रूप में किया जा सकता है (लेकिन आंतरिक कक्षाएं फ़ंक्शन नहीं हैं, क्योंकि वे बहुत अधिक उद्देश्यों की सेवा कर सकते हैं)। यह OOP की तरह ही है - यह कुछ भी ऐसा करने की अनुमति नहीं देता है जिसे आप असेंबली के साथ नहीं कर सकते, लेकिन फिर भी, क्या आप असेंबली में लिखे गए ग्रहण की तरह एक एप्लीकेशन इमेज कर सकते हैं?
होल्गर

3
@ EricDuminil: मेरे लिए, ट्यूरिंग पूर्णता बहुत सैद्धांतिक है। जैसे, जावा ट्यूरिंग पूर्ण है या नहीं, आप जावा में विंडोज डिवाइस ड्राइवर नहीं लिख सकते। (या पोस्टस्क्रिप्ट में, जो पूरी तरह से ट्यूरिंग भी है) जावा में ऐसे फीचर्स जोड़ना जो ऐसा करने की अनुमति देते हैं, इससे उन समस्याओं का सेट बदल जाएगा जिनसे आप इसे हल कर सकते हैं, हालांकि, ऐसा नहीं होगा। इसलिए मैं विधानसभा बिंदु को प्राथमिकता देता हूं; चूंकि आप जो कुछ भी कर सकते हैं, वह निष्पादन योग्य सीपीयू निर्देशों में लागू किया जाता है, ऐसा कुछ भी नहीं है जो आप असेंबली में नहीं कर सकते हैं जो हर सीपीयू निर्देश का समर्थन करता है (ट्यूरिंग मशीन औपचारिकता की तुलना में समझना आसान है)।
होल्गर

2
@abitoito यह सभी उच्च स्तरीय प्रोग्रामिंग कंस्ट्रक्शन के लिए सामान्य है , कम "दृश्यता वास्तव में क्या चल रहा है" प्रदान करने के लिए, जैसा कि यह सब कुछ है, कम विवरण, वास्तविक प्रोग्रामिंग समस्या पर अधिक ध्यान केंद्रित। आप इसे कोड को बेहतर या बदतर बनाने के लिए उपयोग कर सकते हैं; यह सिर्फ एक उपकरण है। वोटिंग फीचर की तरह; यह एक ऐसा उपकरण है, जिसका उपयोग आप किसी पोस्ट की वास्तविक गुणवत्ता के बारे में स्थापित निर्णय प्रदान करने के लिए कर सकते हैं। या आप इसका उपयोग एक विस्तृत, उचित जवाब को कम करने के लिए करते हैं, सिर्फ इसलिए कि आप लंबोदर से नफरत करते हैं।
होल्गर

52

प्रोग्रामिंग भाषाएं निष्पादन के लिए मशीनों के लिए नहीं हैं।

वे प्रोग्रामर के लिए सोचने के लिए हैं।

भाषाएं एक संकलक के साथ एक वार्तालाप हैं जो हमारे विचारों को एक मशीन द्वारा निष्पादित कर सकते हैं। जावा के बारे में लोगों की मुख्य शिकायतों में से एक जो अन्य भाषाओं से आती है (या इसे अन्य भाषाओं के लिए छोड़ देती है ) का इस्तेमाल यह हुआ कि यह प्रोग्रामर पर एक निश्चित मानसिक मॉडल को बल देता है (अर्थात सब कुछ एक वर्ग है)।

मैं इस बात से नहीं तौलना चाहूंगा कि अच्छा हो या बुरा: सब कुछ व्यापार-बंद है। लेकिन Java 8 lambdas प्रोग्रामर को फंक्शन्स के संदर्भ में सोचने की अनुमति देता है , जो कि कुछ ऐसा है जो आप पहले जावा में नहीं कर सकते थे।

यह एक प्रक्रियात्मक प्रोग्रामर के रूप में एक ही बात है जब वे जावा में आते हैं, तो कक्षाओं के संदर्भ में सोचना सीखते हैं : आप देखते हैं कि वे धीरे-धीरे उन कक्षाओं से आगे बढ़ते हैं जो महिमामंडित संरचना वाले होते हैं और स्थैतिक विधियों के एक समूह के साथ 'सहायक' वर्ग होते हैं और कुछ के लिए आगे बढ़ते हैं अधिक बारीकी से एक तर्कसंगत OO डिज़ाइन (mea gupa) जैसा दिखता है।

यदि आप उन्हें गुमनाम आंतरिक वर्गों को व्यक्त करने के लिए एक छोटे तरीके के रूप में सोचते हैं तो आप शायद उन्हें उसी तरह से बहुत प्रभावशाली नहीं पाएंगे, जिस तरह से ऊपर के प्रक्रियात्मक प्रोग्रामर ने शायद नहीं सोचा था कि कक्षाएं किसी भी महान सुधार थीं।


5
उस के साथ सावधान रहें, हालांकि, मुझे लगता था कि OOP सब कुछ था, और फिर मैं बुरी तरह से इकाई-घटक-सिस्टम आर्किटेक्चर (whaddaya मतलब है कि आप प्रत्येक प्रकार के खेल वस्तु के लिए एक वर्ग नहीं है के साथ भ्रमित हो गया?) और प्रत्येक खेल वस्तु OOP ऑब्जेक्ट नहीं है ?!)
user253751

3
दूसरे शब्दों में, OOP में सोचने के बजाय केवल एक अन्य उपकरण के रूप में * o f * कक्षाएं सोचने से, y ने मेरी सोच को बुरे तरीके से प्रतिबंधित कर दिया।
user253751

2
@ मिनीबिस: "ओओपी में सोचने के लिए" बहुत सारे तरीके हैं, इसलिए "कक्षाओं में सोच" के साथ "ओओपी में सोचने" को भ्रमित करने की आम गलती के अलावा, काउंटर उत्पादक तरीके से सोचने के बहुत सारे तरीके हैं। दुर्भाग्य से, यह बहुत बार शुरू से ही सही होता है, क्योंकि किताबें और ट्यूटोरियल हीन लोगों को सिखाते हैं, उदाहरणों में विरोधी पैटर्न दिखाते हैं और उस सोच को फैलाते हैं। "प्रत्येक के लिए एक वर्ग है" की जरूरत है, जो भी हो, सिर्फ एक उदाहरण है, अमूर्तता की अवधारणा के विपरीत, इसी तरह, लगता है "OOP का अर्थ है जितना संभव हो उतना बॉयलरप्लेट लिखना" मिथक, आदि
होल्गर

@immibis हालांकि उस उदाहरण में यह आपकी मदद नहीं कर रहा था, कि किस्सा वास्तव में इस बिंदु का समर्थन करता है: भाषा और प्रतिमान आपके विचारों को संरचित करने और उन्हें एक डिजाइन में बदलने के लिए एक रूपरेखा प्रदान करते हैं। आपके मामले में आप ढांचे के किनारों के खिलाफ भाग गए थे, लेकिन एक अन्य संदर्भ में ऐसा करने से आपको कीचड़ की एक बड़ी गेंद से भटकने और बदसूरत डिजाइन बनाने में मदद मिली होगी। इसलिए, मुझे लगता है, "सब कुछ व्यापार-नापसंद है"। पूर्व मुद्दे से परहेज करते हुए उत्तरार्द्ध लाभ को ध्यान में रखते हुए एक महत्वपूर्ण सवाल यह है कि भाषा बनाने के लिए "बड़ा" कैसे है।
लेहशेंको

@ मिनीबिस यही कारण है कि अच्छी तरह से प्रतिमान का एक गुच्छा सीखना महत्वपूर्ण है : प्रत्येक आपको दूसरों की अपर्याप्तता के बारे में बताता है।
जेरेड स्मिथ

36

कोड की बचत लाइनों को एक नई सुविधा के रूप में देखा जा सकता है, अगर यह आपको एक छोटे और स्पष्ट तरीके से तर्क का एक बड़ा हिस्सा लिखने में सक्षम बनाती है, जिससे दूसरों को पढ़ने और समझने में कम समय लगता है।

लैम्बडा एक्सप्रेशन (और / या मेथड रेफरेंस) के बिना Streamपाइपलाइन बहुत कम पठनीय होती।

उदाहरण के लिए, उदाहरण के लिए, निम्न Streamपाइपलाइन कैसे दिखती होगी यदि आप प्रत्येक लैम्ब्डा अभिव्यक्ति को एक अनाम वर्ग उदाहरण के साथ बदलते हैं।

List<String> names =
    people.stream()
          .filter(p -> p.getAge() > 21)
          .map(p -> p.getName())
          .sorted((n1,n2) -> n1.compareToIgnoreCase(n2))
          .collect(Collectors.toList());

यह होगा:

List<String> names =
    people.stream()
          .filter(new Predicate<Person>() {
              @Override
              public boolean test(Person p) {
                  return p.getAge() > 21;
              }
          })
          .map(new Function<Person,String>() {
              @Override
              public String apply(Person p) {
                  return p.getName();
              }
          })
          .sorted(new Comparator<String>() {
              @Override
              public int compare(String n1, String n2) {
                  return n1.compareToIgnoreCase(n2);
              }
          })
          .collect(Collectors.toList());

यह लैम्बडा एक्सप्रेशन वाले संस्करण की तुलना में लिखना अधिक कठिन है, और यह बहुत अधिक त्रुटि वाला है। इसे समझना भी कठिन है।

और यह अपेक्षाकृत छोटी पाइपलाइन है।

लैम्ब्डा एक्सप्रेशंस और मेथड रेफरेंस के बिना इसे पठनीय बनाने के लिए, आपको उन वेरिएबल्स को परिभाषित करना होगा जो यहां इस्तेमाल किए जा रहे विभिन्न कार्यात्मक इंटरफेस उदाहरणों को पकड़ते हैं, जो पाइपलाइन के तर्क को विभाजित करते हैं, जिससे समझना मुश्किल हो जाता है।


17
मुझे लगता है कि यह एक महत्वपूर्ण अंतर्दृष्टि है। यह तर्क दिया जा सकता है कि एक प्रोग्रामिंग भाषा में कुछ करना व्यावहारिक रूप से असंभव है यदि सिंटैक्टिक और संज्ञानात्मक ओवरहेड उपयोगी होने के लिए बहुत बड़ा है, ताकि अन्य दृष्टिकोण बेहतर होंगे। इसलिए, वाक्यात्मक और संज्ञानात्मक ओवरहेड को कम करके (जैसे लैंबडास अनाम वर्गों की तुलना में करते हैं), उपरोक्त जैसे पाइपलाइन संभव हो जाते हैं। अधिक जीभ-इन-गाल, अगर कोड का एक टुकड़ा लिखने से आपको अपनी नौकरी से निकाल दिया जाता है, तो यह कहा जा सकता है कि यह संभव नहीं है।
सेबेस्टियन रेडल

Nitpick: आप वास्तव में जरूरत नहीं है Comparatorके लिए sortedके रूप में यह वैसे भी प्राकृतिक क्रम में तुलना करती है। शायद तार की लंबाई या समान की तुलना करने के लिए इसे बदल दें, उदाहरण को और बेहतर बनाने के लिए?
तोबियास_क

@tobias_k कोई समस्या नहीं है। मैंने इसे बदलने के compareToIgnoreCaseलिए इसे अलग व्यवहार किया sorted()
एरन

1
compareToIgnoreCaseअभी भी एक बुरा उदाहरण है, जैसा कि आप बस मौजूदा String.CASE_INSENSITIVE_ORDERतुलनित्र का उपयोग कर सकते हैं । @ Tobias_k की लंबाई के आधार पर तुलना करने का सुझाव (या किसी अन्य संपत्ति में बिल्ट-इन-इक्वेटर का न होना) बेहतर बैठता है। अतः क्यू एंड ए कोड उदाहरण से परखने के बाद, lambdas अनावश्यक तुलनित्र कार्यान्वयन का एक बहुत का कारण बना ...
होल्गर

क्या मैं अकेला ऐसा व्यक्ति हूँ जो दूसरा उदाहरण समझता है?
क्लार्क बैटल

8

आंतरिक पुनरावृत्ति

जावा संग्रह को पुनरावृत्त करते समय, अधिकांश डेवलपर्स एक तत्व प्राप्त करते हैं और फिर इसे संसाधित करते हैं। यह है, उस आइटम को बाहर निकालें और फिर उसका उपयोग करें, या उसे पुनः स्थापित करें, आदि जावा के पूर्व -8 संस्करणों के साथ, आप एक आंतरिक वर्ग को लागू कर सकते हैं और कुछ ऐसा कर सकते हैं:

numbers.forEach(new Consumer<Integer>() {
    public void accept(Integer value) {
        System.out.println(value);
    }
});

अब जावा 8 के साथ आप बेहतर और कम क्रिया कर सकते हैं:

numbers.forEach((Integer value) -> System.out.println(value));

या और अच्छा

numbers.forEach(System.out::println);

तर्क के रूप में व्यवहार

निम्नलिखित मामले का अनुमान लगाएं:

public int sumAllEven(List<Integer> numbers) {
    int total = 0;

    for (int number : numbers) {
        if (number % 2 == 0) {
            total += number;
        }
    } 
    return total;
}

Java 8 Predicate इंटरफ़ेस के साथ आप ऐसा कर सकते हैं:

public int sumAll(List<Integer> numbers, Predicate<Integer> p) {
    int total = 0;

    for (int number : numbers) {
        if (p.test(number)) {
            total += number;
        }
    }
    return total;
}

इसे कॉल करना जैसे:

sumAll(numbers, n -> n % 2 == 0);

स्रोत: डीज़ोन - हमें जावा में लैम्ब्डा एक्सप्रेशंस की आवश्यकता क्यों है


संभवतः पहला मामला कोड की कुछ पंक्तियों को सहेजने का एक तरीका है, लेकिन इससे कोड को पढ़ना आसान हो जाता है
अलसीदेर

4
आंतरिक पुनरावृत्ति एक लैम्ब्डा विशेषता कैसे है? तथ्य की साधारण बात यह है कि तकनीकी रूप से लंबोदर आपको कुछ भी ऐसा नहीं करने देते हैं जो आप जावा -8 से पहले नहीं कर सकते थे। यह कोड को पास करने का एक अधिक संक्षिप्त तरीका है।
ओस्मान डी।

@ Aominè इस मामले numbers.forEach((Integer value) -> System.out.println(value));में लैम्ब्डा एक्सप्रेशन दो भागों से बना है, जो कि तीर के सिंबल के बाईं ओर है (->) इसके मापदंडों को सूचीबद्ध करता है और एक इसके शरीर के दाईं ओर होता है । कंपाइलर स्वचालित रूप से यह पता लगाता है कि लैम्ब्डा अभिव्यक्ति में उपभोक्ता इंटरफ़ेस के एकमात्र गैर-कार्यान्वित विधि का एक ही हस्ताक्षर है।
अलसीदेर

5
मैंने यह नहीं पूछा कि एक लंबोदर अभिव्यक्ति क्या है, मैं सिर्फ यह कह रहा हूं कि आंतरिक पुनरावृत्ति का लंबोदर अभिव्यक्तियों से कोई लेना-देना नहीं है।
ओसमैन डी।

1
@ Aominè मैं आपकी बात देख रहा हूं, इसमें प्रति लैंबडास के साथ कुछ भी नहीं है , लेकिन जैसा कि आप बताते हैं, यह एक तरह से साफ करने का तरीका है। मुझे लगता है कि दक्षता के मामले में पूर्व -8 संस्करण के रूप में अच्छा है
अलसीदर

4

निम्न श्रेणी के बजाय आंतरिक वर्ग के बजाय लंबोदा का उपयोग करने के कई लाभ हैं:

  • अधिक भाषा वाक्य रचना शब्दार्थ को प्रस्तुत किए बिना कोड को अधिक कॉम्पैक्ट और अभिव्यंजक बनाएं। आपने पहले ही अपने प्रश्न में एक उदाहरण दिया है।

  • लैम्ब्डा का उपयोग करके आप तत्वों की धाराओं पर कार्यात्मक-शैली के संचालन के साथ प्रोग्रामिंग करने के लिए खुश हैं, जैसे कि संग्रह पर नक्शा-कम रूपांतरण। देख java.util.function और java.util.stream संकुल प्रलेखन।

  • संकलक द्वारा लैम्ब्डा के लिए उत्पन्न कोई भौतिक कक्षाएं फ़ाइल नहीं है। इस प्रकार, यह आपके वितरित अनुप्रयोगों को छोटा बनाता है। मेमने ने लैम्ब्डा को कैसे असाइन किया?

  • यदि लंबर अपने दायरे से बाहर चर का उपयोग नहीं करता है, जिसका अर्थ है कि लंबर का उदाहरण केवल जेवीएम द्वारा एक बार बनाया जाता है, तो कंपाइलर लैम्ब्डा निर्माण का अनुकूलन करेगा। अधिक जानकारी के लिए आप प्रश्न के बारे में @ होल्गर का उत्तर देख सकते हैं क्या विधि संदर्भ जावा 8 में एक अच्छा विचार है?

  • लैम्ब्डा कार्यात्मक इंटरफ़ेस के अलावा मल्टी मार्कर इंटरफेस को लागू कर सकता है, लेकिन गुमनाम आंतरिक वर्ग अधिक इंटरफेस लागू नहीं कर सकते हैं, उदाहरण के लिए:

    //                 v--- create the lambda locally.
    Consumer<Integer> action = (Consumer<Integer> & Serializable) it -> {/*TODO*/};

2

अनाम वर्ग के लिए लैम्ब्डा बस वाक्य रचना चीनी हैं।

लैम्ब्डा से पहले, अनाम कक्षाओं का उपयोग उसी चीज को प्राप्त करने के लिए किया जा सकता है। हर लम्बा अभिव्यक्ति को एक अनाम वर्ग में बदला जा सकता है।

यदि आप IntelliJ IDEA का उपयोग कर रहे हैं, तो यह आपके लिए रूपांतरण कर सकता है:

  • कर्सर को लैम्ब्डा में रखें
  • Alt / विकल्प + एंटर दबाएं

यहाँ छवि विवरण दर्ज करें


3
... मुझे लगा कि @StuartMarks ने पहले से ही लैम्बदास की सिंटैक्टिक शुगर-इट (स्प? ग्र?) को स्पष्ट कर दिया है। ( stackoverflow.com/a/15241404/3475600 , softwareengineering.stackexchange.com/a/181743 )
srborlongan

2

आपके प्रश्न का उत्तर देने के लिए, तथ्य की बात यह है कि लंबोदर आपको कुछ भी ऐसा करने की अनुमति नहीं देते हैं जो आप जावा -8 से पहले नहीं कर सकते, बल्कि यह आपको और अधिक संक्षिप्त कोड लिखने में सक्षम बनाता है । इसका लाभ यह है कि, आपका कोड स्पष्ट और अधिक लचीला होगा।


स्पष्ट रूप से @ होल्गर ने लंबोदर दक्षता के संदर्भ में किसी भी संदेह को समाप्त कर दिया है। यह न केवल कोड क्लीनर बनाने का एक तरीका है, लेकिन अगर लैम्ब्डा किसी भी मूल्य पर कब्जा नहीं करता है, तो यह एक सिंगलटन क्लास (पुन: प्रयोज्य) होगा
अलसीदार

यदि आप गहरी खुदाई करते हैं, तो हर भाषा सुविधा में अंतर होता है। हाथ में प्रश्न उच्च स्तर पर है इसलिए मैंने अपना उत्तर उच्च स्तर पर लिखा है।
ओसमैन डी।

2

एक बात जो मैंने अभी तक नहीं देखी है वह यह है कि एक लैम्ब्डा आपको कार्यक्षमता को परिभाषित करने देता है जहां इसका उपयोग किया जाता है

इसलिए यदि आपके पास कुछ सरल चयन समारोह है, तो आपको इसे बॉयलरप्लेट के एक गुच्छा के साथ एक अलग स्थान पर रखने की आवश्यकता नहीं है, आप बस एक लंबो लिखते हैं जो संक्षिप्त और स्थानीय रूप से प्रासंगिक है।


1

हां इसके कई फायदे हैं।

  • पूरे वर्ग को परिभाषित करने की कोई आवश्यकता नहीं है हम संदर्भ के रूप में इसे स्वयं लागू कर सकते हैं।
    • आंतरिक रूप से कक्षा का निर्माण .class फ़ाइल बनाएगा जबकि यदि आप लैम्ब्डा का उपयोग करते हैं तो क्लास क्रिएशन को कंपाइलर से बचा जाता है क्योंकि लैम्बडा में आप क्लास के बजाय फंक्शन कार्यान्वयन से गुजर रहे हैं।
  • कोड पुन: प्रयोज्य पहले अधिक है
  • और जैसा कि आपने कहा कि कोड छोटा है तो सामान्य कार्यान्वयन।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.