&& (और) और || (या) IF स्टेटमेंट्स में


137

मेरे पास निम्नलिखित कोड हैं:

if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){  
    partialHits.get(z).put(z, tmpmap.get(z));  
}

partialHitsहशपप कहां है।
यदि पहला कथन सत्य है तो क्या होगा? क्या जावा अभी भी दूसरे स्टेटमेंट की जांच करेगा? क्योंकि पहला कथन सत्य होने के लिए, हाशप में दी गई कुंजी नहीं होनी चाहिए, इसलिए यदि दूसरा कथन जांचा जाता है, तो मुझे मिलेगा NullPointerException
तो सरल शब्दों में, अगर हमारे पास निम्न कोड है

if(a && b)  
if(a || b)

bयदि जावा aपहले मामले में गलत है और aदूसरे मामले में सच है तो क्या जावा जाँच करेगा ?

जवाबों:


202

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

if (str != null && !str.isEmpty()) {
  doSomethingWith(str.charAt(0));
}

या फिर इसके विपरीत

if (str == null || str.isEmpty()) {
  complainAboutUnusableString();
} else {
  doSomethingWith(str.charAt(0));
}

यदि हमारे पास जावा में 'शॉर्ट-सर्किट' नहीं है, तो हमें कोड की उपरोक्त पंक्तियों में बहुत सारे NullPointerException प्राप्त होंगे।


क्या बिटवाइज़ तुलनाएं मौजूद हैं ताकि आप दोनों अभिव्यक्तियों का मूल्यांकन कर सकें ? यानी अगर (str! = null | str.isEmpty ())? (बेशक यह एक व्यावहारिक उदाहरण नहीं है, वास्तव में यह बेवकूफी है, लेकिन आपको यह विचार मिलता है)
केजर

5
जब तक अभिव्यक्तियों के दुष्प्रभाव नहीं होते हैं, शॉर्ट-सर्किट शब्दार्थ पूरे तार्किक मूल्यांकन के बराबर होते हैं। यही है, यदि A सत्य है, तो आप A को जानते हैं। B का मूल्यांकन किए बिना ही सत्य है। केवल तभी कोई फर्क पड़ेगा यदि किसी अभिव्यक्ति के दुष्प्रभाव होते हैं। अन्य ऑपरेटरों के लिए के रूप में, आप उपयोग कर सकते हैं *और +तार्किक andऔर or; ((A?1:0) * (B?1:0)) == 1, ((A?1:0) + (B?1:0)) > 0। तुम भी कर सकते हैं xor: ((A?1:0) + (B?1:0)) == 1
दोपहर

1
@ कीज़र: क्या वास्तव में बिटवाइज़ की तुलना है? मुझे लगता है कि यह एक booleanतार्किक (तार्किक) ऑपरेटर है। यह bitwise(पूर्णांक) ऑपरेटर से एक ही प्रतीक होने के बावजूद अलग है ...
user85421

4
जब आप 'और&' और '' के बीच स्विच करना चाहते हैं तो एक आसान ट्रिक || अभिव्यक्तियों को संपूर्ण अभिव्यक्ति को इस तरह से नकारना है: इस तरह से: !(str != null && !str.isEmpty()) बन जाता है: (str !(!=) null !(&&) !(!)str.isEmpty()) और फिर: (str == null || str.isEmpty()) क्योंकि: !(!=) is == !(&&) is || !(!) eliminates itself अन्य सहायक नकारात्मक हैं: !(<) is >= !(>) is <= और इसके विपरीत
egallardo

68

जावा में 5 अलग-अलग बूलियन हैं जो ऑपरेटरों की तुलना करते हैं: &, &&; |,,, ^

& && हैं "और" ऑपरेटर, | और || "या" ऑपरेटर, ^ "Xor" है

एकल पैरामीटर के मानों की जांच करने से पहले, हर पैरामीटर को मानों की परवाह किए बिना जाँचेंगे। डबल वाले पहले बाएं पैरामीटर और उसके मूल्य की जांच करेंगे और अगर true( ||) या false( &&) दूसरे को अछूता छोड़ देंगे। ध्वनि संकलित? एक आसान उदाहरण यह स्पष्ट करना चाहिए:

सभी उदाहरणों के लिए दिया गया:

 String aString = null;

तथा:

 if (aString != null & aString.equals("lala"))

मूल्यांकन किए जाने से पहले दोनों मापदंडों की जांच की जाती है और दूसरे पैरामीटर के लिए NullPointerException को फेंक दिया जाएगा।

 if (aString != null && aString.equals("lala"))

पहले पैरामीटर की जाँच की जाती है और यह वापस आ जाता है false, इसलिए दूसरे पैरामेटर की जाँच नहीं की जाएगी, क्योंकि परिणाम कुछ falseभी हो।

OR के लिए समान:

 if (aString == null | !aString.equals("lala"))

NullPointerException को भी बढ़ाएगा।

 if (aString == null || !aString.equals("lala"))

पहले पैरामीटर की जाँच की जाती है और यह वापस आ जाता है true, इसलिए दूसरे पैरामेटर की जाँच नहीं की जाएगी, क्योंकि परिणाम कुछ trueभी हो।

XOR को अनुकूलित नहीं किया जा सकता है, क्योंकि यह दोनों मापदंडों पर निर्भर करता है।


3
"जावा में 4 अलग-अलग बूलियन हैं जो ऑपरेटरों की तुलना करते हैं: &, &&;;, ||" ... आप ^(xor) भूल रहे हैं ।
अनियोब

ओह, मुझे पता नहीं था कि यह बूलियन बूलियन मानों की जांच करता है। केवल इसे अब तक, बिटमास्क के लिए उपयोग किया जाता है।
हार्डकोड


20

यहाँ सभी उत्तर बहुत अच्छे हैं लेकिन, यह बताने के लिए कि यह कहाँ से आता है, इस तरह के प्रश्नों के लिए स्रोत पर जाना अच्छा है: जावा भाषा विशिष्टता।

धारा 15:23, सशर्त और ऑपरेटर (&&) कहते हैं:

&& ऑपरेटर जैसा है (§15.22.2), लेकिन इसके दाएं हाथ के ऑपरेंड का मूल्यांकन केवल तभी करता है जब इसके बाएं हाथ के ऑपरेंड का मूल्य सही हो। [...] रन समय में, बाएं हाथ की ऑपरेंड अभिव्यक्ति का मूल्यांकन पहले किया जाता है [...] यदि परिणामी मूल्य गलत है, तो सशर्त-और अभिव्यक्ति का मूल्य गलत है और दाहिने हाथ की ऑपरेंड अभिव्यक्ति का मूल्यांकन नहीं किया गया है । यदि बाएं हाथ के ऑपरेंड का मूल्य सही है, तो दाहिने हाथ की अभिव्यक्ति का मूल्यांकन किया जाता है [...] जिसके परिणामस्वरूप मूल्य सशर्त-और अभिव्यक्ति का मूल्य बन जाता है। इस प्रकार, && बूलियन ऑपरेंड्स के समान परिणाम की गणना करता है। यह केवल इस बात में भिन्न होता है कि दाएं हाथ की ऑपरेंड अभिव्यक्ति का मूल्यांकन हमेशा के बजाय सशर्त रूप से किया जाता है।

और इसी तरह, धारा 15:24, सशर्त-संचालक (()) , कहते हैं:

|| ऑपरेटर की तरह है | (Its15.22.2), लेकिन इसके दाएं हाथ के ऑपरेंड का मूल्यांकन केवल तभी करता है, जब इसके बाएं हाथ के ऑपरेंड का मूल्य गलत हो। [...] रन समय में, बाएं हाथ की ऑपरेंड अभिव्यक्ति का मूल्यांकन पहले किया जाता है; [...] यदि परिणामी मूल्य सत्य है, तो सशर्त-या अभिव्यक्ति का मूल्य सत्य है और दाहिने हाथ की ऑपरेंड अभिव्यक्ति का मूल्यांकन नहीं किया जाता है। यदि बाएं हाथ के संचालन का मूल्य गलत है, तो दाहिने हाथ की अभिव्यक्ति का मूल्यांकन किया जाता है; [...] परिणामी मूल्य सशर्त-या अभिव्यक्ति का मूल्य बन जाता है। इस प्रकार, || के रूप में एक ही परिणाम की गणना करता है बूलियन या बूलियन ऑपरेंड पर। यह केवल इस बात में भिन्न होता है कि दाएं हाथ की ऑपरेंड अभिव्यक्ति का मूल्यांकन हमेशा के बजाय सशर्त रूप से किया जाता है।

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

int x = (y == null) ? 0 : y.getFoo();

बिना NullPointerException के।


6

नहीं, यदि कोई सच है (एक orपरीक्षण में), बी का परीक्षण नहीं किया जाएगा, क्योंकि परीक्षण का परिणाम हमेशा सच होगा, जो भी बी अभिव्यक्ति का मूल्य है।

एक साधारण परीक्षण करें:

if (true || ((String) null).equals("foobar")) {
    ...
}

नहीं फेंक देंगे NullPointerException!


6

यहां शॉर्ट सर्किट का मतलब है कि दूसरी स्थिति का मूल्यांकन नहीं किया जाएगा।

यदि (A && B) परिणाम होगा तो शॉर्ट सर्किट यदि A गलत है।

यदि (A && B) ए शॉर्ट है तो शॉर्ट सर्किट नहीं होगा ।

यदि (ए || बी) शॉर्ट सर्किट का परिणाम होगा यदि ए ट्रू है।

अगर (A || B) शॉर्ट सर्किट नहीं होगा तो A गलत है।


4

नहीं, यह शॉर्ट सर्किट होगा और परिणाम जानने के बाद जावा मूल्यांकन करना बंद कर देगा।


4

हां, बूलियन अभिव्यक्तियों के लिए शॉर्ट-सर्किट मूल्यांकन सभी सी-लाइक परिवार में डिफ़ॉल्ट व्यवहार है।

एक दिलचस्प तथ्य यह है कि एक्सप्रेशन में सभी शब्दों का मूल्यांकन करने के लिए जावा &और |लॉजिक ऑपरेंड्स के रूप में (वे ओवरलोडेड होते हैं, intप्रकार के साथ वे अपेक्षित बिटवाइज़ ऑपरेशंस) का उपयोग करते हैं, जो आपको साइड-इफेक्ट्स की आवश्यकता होने पर भी उपयोगी होता है।


यह याद रखना दिलचस्प है: उदाहरण के लिए एक विधि परिवर्तन (डेटा) दिया गया है जो एक बूलियन देता है, फिर: यदि (a .hangeData (डेटा) || b.changeData (डेटा)) {doSomething ()? } परिवर्तन नहीं करेगा b। परिवर्तन पर अगर a.changeData () सही है, लेकिन अगर (। a.changeData (डेटा) | b.changeData (डेटा)) {doSomething ()} दोनों और b, दोनों में परिवर्तन () को निष्पादित करता है। अगर एक लौटाया सच पर आह्वान किया।
संपाि

0

यह & && के बीच मूल अंतर पर वापस जाता है, | और ||

BTW आप एक ही कार्य कई बार करते हैं। सुनिश्चित नहीं है कि दक्षता एक मुद्दा है। आप कुछ नकल निकाल सकते हैं।

Z z2 = partialHits.get(req_nr).get(z); // assuming a value cannout be null.
Z z3 = tmpmap.get(z); // assuming z3 cannot be null.
if(z2 == null || z2 < z3){   
    partialHits.get(z).put(z, z3);   
} 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.