लैंबडा अभिव्यक्ति बनाम विधि संदर्भ [बंद]


114

इंटेलीजे मुझे अपने लैम्बडा के भावों को विधि संदर्भों से बदलने का प्रस्ताव देता रहता है।

क्या दोनों में कोई वस्तुगत अंतर है?


4
वास्तव में नहीं, मुझे कोई वस्तु दिखाई नहीं दे रही है! यह मेरे लिए एक स्थिर कॉल की तरह दिखता है
जेरार्ड

9
बेशक! लेकिन "आपको नहीं मिल रहा है" या तो ... यह स्वाद की बात है, मैं अधिक तकनीकी पहलुओं के बारे में अधिक चिंतित था। वास्तव में, जैसा कि आपने पहले ही कहा था कि वे एक ही हैं, यह मेरे लिए एक अच्छा जवाब है। वैसे भी, जैसा कि इंटेलीज ने इसका प्रस्ताव रखा है, मुझे लगता है कि लैंबडा की तुलना में विधि संदर्भ देखने के लिए आमतौर पर इसकी सराहना की जाती है (मेरे लिए नहीं, हालांकि)।
जेरार्ड

15
लैम्बडा अभिव्यक्ति का कोड एक सिंथेटिक विधि से संकलित किया जाता है, जबकि विधि संदर्भ के बिना काम करती है (अपवाद: विशेष निर्माण जैसे Type[]::new)। रनटाइम पर उत्पन्न अनाम वर्ग समान होगा। JRE को उनके बीच कोई फर्क नहीं पड़ता है। इसलिए एक विधि संदर्भ का उपयोग करने से आपके संकलित कोड में एक विधि बच जाएगी, दूसरी ओर, आप चरण-दर-चरण डिबगिंग करते समय उन्हें रोक नहीं सकते ...
Holger

6
अब यह सवाल बंद होने जा रहा है ... मेरे जैसे सभी उपयोगकर्ताओं के लिए बहुत बुरा है कि लैंबडास और संदर्भों के बीच अंतर नहीं पता है, भले ही कोई निर्णायक न हो। मुझे भी आश्चर्य है कि किसी ने भी इसका जवाब देने की हिम्मत क्यों नहीं की? यह मेरे लिए सही जवाब है।
गेरार्ड

3
दो साल पुराने बंद प्रश्न का उत्तर देना शायद एक बुरा विचार है, लेकिन उन लोगों के लिए जो प्रश्न को पढ़ते हैं, यह वही है जो ओरेकल के ट्यूटोरियल ( docs.oracle.com/javase/tutorial/java/javaOO/… ) कहते हैं: विधि संदर्भ ... हैं पहले से ही एक नाम है विधियों के लिए कॉम्पैक्ट, आसानी से पढ़ा जाने वाला लैम्बडा भाव।
कल

जवाबों:


187

मुझे इस बात पर कुछ परिप्रेक्ष्य देने की आवश्यकता है कि हमने इस सुविधा को भाषा में क्यों जोड़ा, जब स्पष्ट रूप से हमें इसकी सख्त आवश्यकता नहीं थी (सभी तरीकों के रिफ को लंबोदा के रूप में व्यक्त किया जा सकता है।)

ध्यान दें कि कोई सही उत्तर नहीं है । जो कोई भी कहता है कि "हमेशा एक मेमने के बजाय एक विधि रेफरी का उपयोग करें" या "हमेशा एक विधि रेफरी के बजाय एक मेमने का उपयोग करें" को अनदेखा किया जाना चाहिए।

यह प्रश्न "जब मैं एक अनाम वर्ग बनाम एक अनाम वर्ग का उपयोग करना चाहिए" भावना में बहुत समान है? और उत्तर एक ही है: जब आप इसे अधिक पठनीय पाते हैं । निश्चित रूप से ऐसे मामले हैं जो निश्चित रूप से एक या निश्चित रूप से दूसरे हैं, लेकिन बीच में ग्रे का एक मेजबान है, और निर्णय का उपयोग किया जाना चाहिए।

विधि refs के पीछे सिद्धांत सरल है: नाम मायने रखता है । यदि किसी विधि में नाम है, तो कोड के अनिवार्य बैग के बजाय नाम से इसका उल्लेख करना, जो अंततः बस चारों ओर मुड़ता है और आक्रमण करता है, अक्सर (लेकिन हमेशा नहीं!) अधिक स्पष्ट और पठनीय होता है।

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

इस पद्धति के बारे में एक महत्वपूर्ण विचार यह है कि क्या विधि स्पष्ट करती है या इरादे को बाधित करती है या नहीं, यह इस संदर्भ से स्पष्ट है कि प्रतिनिधित्व किए गए फ़ंक्शन का आकार क्या है। कुछ मामलों में (उदाहरण के लिए, map(Person::getLastName)यह इस संदर्भ से काफी स्पष्ट है कि एक फ़ंक्शन जो किसी चीज़ को दूसरे से मैप करता है, और इस तरह के मामलों में, विधि संदर्भ चमक जाती है। दूसरों में, विधि रेफरी का उपयोग करके पाठक को आश्चर्य होता है कि किस तरह का है। फ़ंक्शन का वर्णन किया जा रहा है, यह एक चेतावनी का संकेत है कि एक लंबोदर अधिक पठनीय हो सकता है, भले ही यह लंबा हो।

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


25
@Gerard धन्यवाद आप एक बेहतर जवाब होगा।
यिसन हज्ज

3
@Gardard लगता है कि ब्रायन कह रहा है "नहीं, वहाँ नहीं है"
dj18

ब्रायन, मुझे एक विधि संदर्भ और एक ही विधि के लिए एक लैम्ब्डा का उपयोग करके अलग-अलग परिणाम मिलते हैं। क्या उन्हें विनिमेय नहीं होना चाहिए?
मिशेल फ़िनस्टीन

@mFeinstein प्रत्येक विधि रेफ के लिए, एक समान लैम्ब्डा है (जिसका उपयोग आप कर सकते हैं या नहीं भी कर सकते हैं)। प्रश्न के रूप में कोड पोस्ट करें?
ब्रायन गोएट्ज़

मैं चाहता हूं, लेकिन मुझे डर है कि कोड बहुत बड़ा हो सकता है, क्योंकि यह एक एंड्रॉइड है LiveData, एक के अंदर Fragment, जिसे मैंने कन्वर्ट किया है Eventजो एक ट्रिगर होता है ViewModel... और अलग व्यवहार तब होता है जब एंड्रॉइड उसी पर वापस जाता है Fragment.. .तो मुझे एक कठिन समय एक प्रश्न के लिए सरल कर रहा है
मिशेल फेन्सटीन

10

कई बयानों से युक्त लंबे लंबोदर भाव आपके कोड की पठनीयता को कम कर सकते हैं । ऐसे मामले में, उन कथनों को एक विधि में निकालना और इसे संदर्भित करना बेहतर विकल्प हो सकता है।

दूसरा कारण पुन: प्रयोज्य हो सकता है । अपने लैंबडा अभिव्यक्ति को कुछ बयानों की प्रतिलिपि बनाने और चिपकाने के बजाय, आप एक विधि का निर्माण कर सकते हैं और इसे अपने कोड के विभिन्न स्थानों से कॉल कर सकते हैं।


3
तुलना: houses.map(House::getName)और houses.map(h -> h.getName())। लंबोदर दो कम वर्ण लेता है। यह सच है कि प्रकार स्पष्ट नहीं है, लेकिन कोई भी आईडीई आपको बताएगा, और इसके अलावा, लंबोदर का उपयोग तब किया जाना चाहिए जब प्रकार स्पष्ट हो। मैं आपके साथ पुन: प्रयोज्यता से सहमत हो सकता हूं, लेकिन लैम्ब्डा ठीक छोटे हैं, इसलिए उन्हें बड़े विशिष्ट तरीकों को बनाने के बजाय जंजीर बनाया जा सकता है। उस अर्थ में, छोटे तरीके कुछ बड़ी और जटिल विधि की तुलना में अधिक पुन: प्रयोज्य होते हैं, और लंबोदर की स्पष्टता (और कुछ हद तक, वाचालता) के कारण वे अभी भी पढ़ने में आसान हैं।
जेरार्ड

11
मैं जेराल्ड के साथ हूं। पठनीयता वास्तव में तब होती है जब आप कोड को स्थानांतरित करते हैं, इसलिए आपको पढ़ने के लिए इसे कूदना पड़ता है, फिर वापस कूदना होता है। आप एक ही स्थान पर सभी प्रासंगिक कोड रखना चाहते हैं । इसके अलावा, Houseएक बहुत ही सौम्य उदाहरण है; किस बारे में ThreeStoryRedBrickHouseWithBlueDoors। मैं कई-तर्क वाले लैम्ब्डा के लिए विधि संदर्भों को प्राथमिकता देता हूं, और कभी-कभी इस बात पर जोर देने के लिए कि लैम्ब्डा केवल एकल विधि कॉल के बारे में है। एक विधि संदर्भ के साथ गलत होने के लिए कम है: आप उपयोग स्थल पर तर्क को गलत कर सकते हैं, गलती से बाहरी दायरे से एक चर का जिक्र कर सकते हैं, आदि
मार्को टोपोलनिक

@Gardard मैं आपके पहले बयान से असहमत हूं। यदि आप विधि के नामों का वर्णन करने में अच्छी तरह से उपयोग करते हैं और यदि आप कोड के बड़े ढेर निकालते हैं, तो मूविंग कोड पठनीयता में सुधार करता है। यदि आप obfuscating विधि नामों का उपयोग करते हैं तो मैं आपसे सहमत हूं।
टॉरस्टेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.