अगर हालत में set.add () की बूलियन वापसी?


15

सेट क्लास का ऐड ऑपरेटर एक बूलियन देता है जो कि अगर तत्व (जो जोड़ा जाना है) सही नहीं है, तो पहले से ही गलत है। लिख रहा है

if (set.add(entry)) {
    //do some more stuff
}

स्वच्छ कोड लिखने के मामले में अच्छी शैली मानी जाती है? मैं सोच रहा हूं कि आप एक साथ दो काम करते हैं। 1) तत्व को जोड़ने और 2) जाँच करना कि क्या तत्व मौजूद है।


6
आप मानक के बारे में बात कर रहे हैं java.util.Set, जो addउस समय सही है जब तत्व पहले से ही नहीं था, है ना?
user2357112

1
मैं आमतौर पर विपरीत परीक्षण पर विचार if (!set.add(entry)) {// entry already present, possibly a case you want to handle}
करूंगा

क्या एक साथ दो काम करने में कुछ गड़बड़ है?
user207421

@ user2357112 हाँ, यह सही है।
एंड्रियास ब्रौन

जवाबों:


19

हाँ यही है।

ऑपरेशन के बूलियन मान को वापस करने का सामान्य बिंदु यह है कि आप इसका उपयोग निर्णय लेने के लिए कर सकते हैं, अर्थात एक ifनिर्माण के भीतर । इस क्षमता को महसूस करने का एकमात्र तरीका यह होगा कि आप रिटर्न वैल्यू को एक वैरिएबल में स्टोर करें और फिर तुरंत इसे एक में पुनः उपयोग करें if, जो कि केवल मूर्खतापूर्ण है और निश्चित रूप से लिखने के लिए बेहतर नहीं है if(operation()) { ... }। तो बस आगे बढ़ें और ऐसा करें, हम आपको (उसके लिए) जज नहीं करेंगे।


आपके उत्तर के लिए धन्यवाद। जैसा कि @Niels vanReijmersdal ने अपने उत्तर में बताया कि ऐसा करने से कमांड और क्वेरी अलगाव टूट जाता है, है ना? क्या आपको नहीं लगता कि यह मायने रखता है?
एंड्रियास ब्रौन

4
@AndreasBraun व्यक्तिगत रूप से मुझे लगता है कि कमांड क्वेरी पृथक्करण गूंगा है। किसी कार्य को करने और उस क्रिया से संबंधित मान वापस करने के लिए एक विधि के लिए यह अक्सर तार्किक होता है। दोनों के बीच एक कृत्रिम जुदाई को लागू करने से अनावश्यक रूप से वर्बोज़ कोड होता है।

1
@ dan1111: वास्तव में। इसके अलावा, "कमांड और क्वेरी सेपरेशन" "चेक एक्ट" और समान विरोधी पैटर्न की ओर जाता है, जो बहु-थ्रेडेड संदर्भों में टूट सकता है। इस तरह की जुदाई का विज्ञापन करना अजीब है, जब एक ही समय में शेष दुनिया मजबूत और कुशल एसएमपी समाधानों के लिए परमाणु फ्यूज्ड संचालन बनाने की कोशिश कर रही है ...
होल्गर

2
@ Jörg W Mittag: पेज 759 किस का? चूँकि एक परमाणु ऑपरेशन आंतरिक रूप से "जाँच करें तो अधिनियम" विरोधी पैटर्न के खिलाफ प्रतिरक्षा है, इसलिए इसे जो भी पता लगाना है, निर्माण धागा को सुरक्षित कैसे बनाया जाए, इसके बारे में "संपूर्ण अध्याय" पढ़ने के लिए इसे विभाजित करने के लिए फायदेमंद नहीं दिखता है। फिर। चूँकि आपने कोई वास्तविक तर्क नहीं दिए थे, इसलिए मुझे उन तर्कों पर "कोई विशेष आपत्ति नहीं है"।
होल्गर

1
@ Jörg W Mittag: खैर, मैं इस पृष्ठ पर उत्तर के बारे में बात कर रहा हूं, Set.addएक विकल्प का नाम लिए बिना एकल ऑपरेशन के रूप में उपयोग करने को हतोत्साहित करता हूं । यदि इच्छित ऑपरेशन में एकल तत्व जोड़ना है और यह पता लगाना है कि क्या इसे जोड़ा गया है, तो अधिक शक्तिशाली विकल्प की आवश्यकता नहीं है जो अभी भी लाभ के बिना ऑपरेशन को जटिल बनाता है। मुझे आशा है कि आप इस बात Set.addसे अवगत होंगे कि यह एक अंतर्निहित JRE विधि है जिसका उपयोग बिना पहले 700०० पेज की किताब के अध्ययन के बिना किया जा सकता है।
होल्गर

12

मैं कहूंगा कि यह जितना संभव हो उतना साफ नहीं है, क्योंकि यह अनुरक्षक को या तो पहले से ही पता करने के लिए मजबूर करता है या वापसी मूल्य का संकेत देता है। क्या इसका मतलब है कि पहले से मौजूद मूल्य, पहले से मौजूद नहीं था, सफलतापूर्वक डाला गया था? यदि आप इसका उपयोग नहीं करते हैं, तो आप नहीं जान पाएंगे, और यदि आप करते हैं, तो भी यह बहुत अधिक मानसिक भार है।

मैं निम्नलिखित पसंद करूंगा:

boolean added = set.add(entry);

if (added) {
    //do some more stuff
}

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



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

9
मैं दूसरा @Holger। यदि आप नहीं जानते Set.add, तो आप अनुभवहीन हैं और आपको उन्हें सीखने और अधिक अनुभवी बनने के लिए इन तरीकों को देखना चाहिए
मोनिका

7
notAlreadyPresentसबसे अच्छा शब्द नहीं है। मैं यह addedजानने के लिए कि पाठक एक मूल्य को सेट में क्यों नहीं जोड़ा जाएगा, मैं उसका उपयोग करूंगा , और उम्मीद करता हूं।
njzk2

3
@JustinTime: कोड का वर्णन करने के लिए टिप्पणियों का उपयोग करना व्यापक रूप से बुरा व्यवहार माना जाता है। आपका कोड स्व-वर्णन होना चाहिए। एक कोड समीक्षा में, मैं आपके उदाहरण को अस्वीकार्य मानूंगा।
ब्लूराजा - डैनी पफ्लुघोफ्ट

8

अगर सच का मतलब सफलता है, तो यह अच्छा है, स्पष्ट कोड है।

एक व्यापक सम्मेलन है कि सफलता पर एक फ़ंक्शन या विधि सही (या कुछ ऐसा है जो सत्य का मूल्यांकन करती है) लौटाती है। जब तक आपका कोड इस प्रकार है, मुझे लगता है कि सशर्त में विधि ठीक है।

इस तरह कोड मेरे विचार में अनावश्यक रूप से बरबाद है:

boolean frobulate_succeeded = thing.frobulate();

if (frobulate_succeeded) {
    ...
}

ऐसा महसूस होता है कि आप खुद को दोहरा रहे हैं।

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


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

@ सोलोमनऑफ़सर्किट इस मामले में, एक अपवाद का अर्थ है कि सेट ने तत्व को जोड़ने से इनकार कर दिया, falseइसका मतलब है कि तत्व को जोड़ा नहीं गया था क्योंकि यह पहले से ही निहित था, और trueइसका मतलब है कि तत्व पहले से ही निहित नहीं था। जैसा add()कि सेट trueमें तत्व को जोड़ा जाता है यदि सेट में पहले से ही इसे शामिल नहीं किया गया था, इसलिए इसका मतलब है कि तत्व को सेट में सफलतापूर्वक जोड़ा गया था।
जस्टिन टाइम - मोनिका

@JustinTime आप दो मामलों में अपने स्वयं के मूल्य निर्णय जोड़ रहे हैं। एक और व्याख्या यह है कि सफलता यह है कि आइटम सेट में है जब विधि वापस आती है। यदि आइटम पहले से ही सेट में था, addतो कुछ भी किए बिना सफल होता है। यदि आइटम पहले से सेट में नहीं था, addतो आइटम को सेट में जोड़कर सफल होता है। जो व्याख्या सही है वह मनमानी है। सफलता की कम मनमानी परिभाषा भाषा से एक है: यदि यह सामान्य रूप से वापस आती है तो विधि सफल होती है।
मोनिका

1
सफलता की कम से कम मनमानी परिभाषा यह है कि विधि ने उस कार्य को सफलतापूर्वक निष्पादित किया जो प्रदर्शन करने के लिए निर्धारित है। यदि मेरे पास कोई विधि है firstLessThanSecond(int l, int r), और यह वापस आती trueहै l > rया falseनहीं l <= r, तो वह विधि सफल नहीं होती है , भले ही यह सामान्य रूप से वापस आती हो।
जस्टिन टाइम -

1
@JustinTime addअनुबंध का एक गंभीर संक्षिप्त नाम है। प्रलेखन "पहले से मौजूद नहीं है, तो इस सेट के लिए निर्दिष्ट तत्व जोड़ता है", जो संतुष्ट है कि क्या आइटम पहले से ही सेट में था या नहीं। आप चाहे तो वापसी मूल्य की व्याख्या करने के लिए स्वतंत्र हैं लेकिन अंततः यह केवल आपकी व्याख्या है। और आपके दूसरे उदाहरण में विधि का मूल्यांकन करता है कि क्या कोई शर्त सही है। यदि स्थिति झूठी है, तो विधि निश्चित रूप से विफल नहीं हुई है, क्योंकि इसने सशर्त का सफलतापूर्वक मूल्यांकन किया है।
मोनिका

2

मैं कहूंगा कि यह बहुत सी-लाइक है। अधिकांश समय मैं एक उत्परिवर्तन परिणाम के लिए एक वर्णनात्मक नाम वाले चर के लिए पसंद करूंगा, और कोई उत्परिवर्तन नहीं होगाif स्थिति ।

एक कंपाइलर इस वैरिएबल को खत्म कर देगा अगर इसका तुरंत पुन: उपयोग किया जाए। एक मानव के पास स्रोत पढ़ने में आसान समय होगा; मेरे लिए, यह अधिक महत्वपूर्ण है।

यदि किसी को शर्त में and/ orखंड जोड़कर स्थिति का विस्तार करना चाहिए , तो वे .add()शॉर्ट-सर्किट मूल्यांकन के कारण कुछ मामलों में कॉल नहीं कर सकते हैं । जब तक शॉर्ट-सर्कुलेटिंग विशेष रूप से प्रत्याशित न हो, यह बग के रूप में समाप्त हो सकता है।


अगर मैं लिखूं if (set.contains(entry)){set.add(entry); //do more stuff}कि क्या यह भी संकलक द्वारा समाप्त हो गया है?
एंड्रियास ब्रौन

1
@AndreasBraun: मुझे ऐसा नहीं लगता; संकलक के बीच containsऔर अर्थ लिंक के बारे में कोई पता नहीं है add। इसके अलावा, यह entryसेट में देखने का दोहरा काम करता है ; यह बहुत बड़े सेट और बहुत हल्के छोरों के लिए एक भूमिका निभा सकता है।
9000

1
इसलिए मैं इसे लेता हूं आप नहीं लिखेंगे, if (set.contains(entry)){set.add(entry); //do more stuff}बल्कि इसके बजाय उदाहरण के लिए कार्ल बेवेलफेल्ड के उत्तर पर जाएं।
एंड्रियास ब्रौन

@AndreasBraun: बिल्कुल (उस जवाब को उकेरा)।
9000

1
एक अच्छी बात है। यदि भविष्य के देव में शॉर्ट-सर्किट के साथ अन्य स्थितियां हो सकती हैं, तो आईएफए में म्यूटेशन मुश्किल हैं।
njzk2

0

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

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

- ऑब्जेक्ट्स ओरिएंटेड एनालिसिस और डिजाइन ऑफ एप्लीकेशन के साथ ग्रैडी बोच लेखक ”

मेरे लिए आपके कोड का इरादा स्पष्ट नहीं है। यदि एंट्री सक्सेसफुल होने पर दोनों को अंजाम दिया जाता है, या जब यह पहले से मौजूद है तो भी? क्या add()लौटाता है? मद # जिंस? त्रुटि कोड?


2
खैर, हाँ, यही मैंने भी सोचा था। लेकिन मुझे भी लगता है कि @Kilian Foth के पास एक बिंदु है। अगर मैं क्वेरी और आदेश को अलग करना चाहता हूं तो मुझे लिखना होगा if (set.contains(entry)){set.add(entry); //do more stuff}जो मूर्खतापूर्ण लगता है। इस पर आपका क्या ख्याल है?
एंड्रियास ब्रौन

मैं एक अच्छे नाम का सुझाव देने के लिए इस कोड के डोमेन और संदर्भ को नहीं जानता, लेकिन मैं इसे स्पष्ट इरादे के साथ एक फ़ंक्शन में लपेटूंगा। उदाहरण के लिए: doesEntryExistOrCreateEntry (प्रविष्टि), इसमें आपका समाहित () + जोड़ () तर्क हो सकता है और बूलियन वापस आ सकता है। इसी तरह का प्रश्न यहां: softwareengineering.stackexchange.com/questions/149708/… जो स्वच्छ कोड के बाहर इस अभ्यास पर चर्चा करता है।
नील्स वैन रीजर्सडाल

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

1
"क्या जोड़ता है () वापसी?" मैं किसी भी जावा डेवलपर से अपेक्षा करता हूं जो Collectionएपीआई को जानने के लिए कोड समीक्षा करता है ।
njzk2

3
@ Dan1111 से सहमत हैं। यह विशेष रूप से गूंगा है क्योंकि यह चीजों की तरह है जो दौड़ की स्थिति के लिए उपजाऊ जमीन बनाता है।
पॉल ड्रेपर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.