2009-11-25 19 views
101

मेरा प्रश्न बहुत बुनियादी हो सकता है लेकिन फिर भी मुझे लगता है कि यह पूछने लायक है।और& (AND) और || (या) IF कथन

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 एक HashMap है: मैं निम्नलिखित कोड है। क्या होगा यदि पहला कथन सत्य है? जावा अभी भी दूसरे कथन की जांच करेगा? क्योंकि पहला कथन सत्य होने के लिए, हैश मैप में दी गई कुंजी नहीं होनी चाहिए, इसलिए यदि दूसरा कथन चेक किया गया है, तो मुझे NullPointerException मिल जाएगा।
तो सरल शब्दों में, अगर हम निम्नलिखित कोड है

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

होगा जावा जांच b अगर a पहले मामले में गलत है और अगर a दूसरे मामले में सही है?

उत्तर

158

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

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

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

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

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

+0

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

+5

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

+1

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

27

नहीं, यह चेक नहीं किया जाएगा। इस व्यवहार को short-circuit evaluation कहा जाता है और जावा सहित कई भाषाओं में एक विशेषता है।

+2

@ अज़ीमुथ: आपका स्वागत है। यदि आप कुछ नहीं जानते हैं, तो इसे ठीक करने का सबसे अच्छा तरीका पूछना है। –

5

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

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

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

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

4

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

18

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

Section 15:23, Conditional-And operator (&&), कहते हैं:

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

और इसी तरह, Section 15:24, Conditional-Or operator (||), कहते हैं:

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

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

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

4

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

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

+0

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

51

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

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

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

सारे उदाहरण के लिए दिया गया है:

String aString = null; 

और:

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

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

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

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

उसी के लिए या:

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

NullPointerException भी बढ़ा देंगे।

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

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

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

+2

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

+0

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

0

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

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

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); 
} 
4

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

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

हैं (ए & & बी) होगा शॉर्ट सर्किट में नहीं परिणाम अगर एक सच्ची है।

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

हैं (ए || बी) होगा शॉर्ट सर्किट में नहीं परिणाम अगर एक झूठी है।

संबंधित मुद्दे