2016-02-04 5 views
9

तो अगर मैं एक Name वस्तु है और प्रकार Name (names) के एक ArrayList है, और मुझे पता लगाने के लिए कि क्या नामों की सूची को किसी दिए गए Name वस्तु (n) शामिल हैं चाहते हैं, मैं इसे दो कर सकता है तरीके:जावा बनाम anyMatch व्यवहार होता है

boolean exists = names.contains(n); 

या

boolean exists - names.stream().anyMatch(x -> x.equals(n)); 

हैं कि ये दोनों एक ही व्यवहार करते हैं और उसके बाद क्या होता है अगर nसौंपा गया था के बारे में सोचा होगा मैं विचार कर रहा था?

जैसा कि मैं समझता हूं, अगर तर्क null है, तो यह true देता है यदि सूची में null है। मैं यह anyMatch कैसे प्राप्त करूं - क्या यह Objects.equals(x, n) का उपयोग करके होगा?

यदि यह काम करता है, तो कौन सा दृष्टिकोण अधिक कुशल है - क्या यह anyMatch है क्योंकि यह आलस्य और समांतरता का लाभ उठा सकता है?

+0

'नाम' प्रकार क्या है? – Tunaki

+1

यदि 'नाम' वास्तव में 'ऐरेलिस्ट' है, तो मुझे लगता है कि प्रदर्शन समान होगा। लेकिन अगर यह 'हैशसेट' जैसा कुछ है तो एक 'है' कॉल लगभग निश्चित रूप से अधिक कुशल होगा (क्योंकि इसे वास्तव में तत्वों के माध्यम से लूप करने की आवश्यकता नहीं है)। –

+0

@ जोचिमसौयर उन्होंने * कहा * कि यह एक 'ऐरेलिस्ट' है। यह मानना ​​कम से कम उचित है कि यह सच है। – Marco13

उत्तर

10

धारा आधारित संस्करण के साथ समस्या यह है कि अगर संग्रह (और इस तरह अपनी स्ट्रीम) null तत्व शामिल हैं, तो विधेय एक NullPointerException जब यह इस null वस्तु पर equals कॉल करने के लिए कोशिश करता है फेंक नहीं है।

यह

boolean exists = names.stream().anyMatch(x -> Objects.equals(x, n)); 

साथ बचा जा सकता है लेकिन वहाँ कोई व्यावहारिक लाभ इस मामले में धारा आधारित समाधान के लिए उम्मीद की जानी है। समांतरता वास्तव में बड़ी सूचियों के लिए एक लाभ ला सकती है, लेकिन किसी को parallel() में आकस्मिक रूप से फेंकना नहीं चाहिए और यह मानते हुए कि चीजों को तेज़ी से बना सकता है। सबसे पहले, आपको वास्तविक बाधाओं को स्पष्ट रूप से पहचानना चाहिए।

और पठनीयता के मामले में, मैं यहां पहला, शास्त्रीय समाधान पसंद करूंगा। यदि आप यह जांचना चाहते हैं कि names.contains(aParticularValue) की सूची है, तो आपको यह करना चाहिए - यह सिर्फ गद्य की तरह पढ़ता है और इरादा स्पष्ट करता है।

संपादित

contains दृष्टिकोण का एक और लाभ टिप्पणी में और अन्य जवाब में उल्लेख किया गया था, और कहा कि यहां उल्लेख के लायक हो सकता है: अगर names संग्रह के प्रकार बाद में बदल गया है, के लिए उदाहरण के लिए, HashSet होने के लिए, आपको तेजी से contains -check (ओ (एन) के बजाय ओ (1) के साथ मुफ्त में प्राप्त होगा - कोड के किसी अन्य भाग को बदले बिना। स्ट्रीम-आधारित समाधान को तब भी सभी तत्वों को फिर से चालू करना होगा, और इसमें काफी कम प्रदर्शन हो सकता है।

+0

इसके अलावा: * यदि * प्रदर्शन प्रासंगिक हो जाता है, तो एक अलग डेटा प्रकार पर स्विच करना उस पर समांतरता को फेंकने के बजाय प्रदर्शन में सुधार करने का एक आसान तरीका है ('लिंक्ड हैशसेट' या इसी तरह, अगर आदेश को बनाए रखने की आवश्यकता है)। –

1

उन्हें उसी परिणाम प्रदान करना चाहिए यदि hashCode() और equals() उचित तरीके से लिखे गए हैं।

लेकिन प्रदर्शन पूरी तरह से अलग हो सकता है। सूची के लिए इससे कोई फर्क नहीं पड़ता है, लेकिन हैशसेट तत्व का पता लगाने के लिए hashCode() का उपयोग करेगा और यह निरंतर समय में (संभवतः) किया जाएगा।दूसरे समाधान के साथ यह सभी वस्तुओं पर लूप होगा और एक समारोह को कॉल करेगा, इसलिए रैखिक समय में किया जाएगा।

यदि एन शून्य है, वास्तव में कोई फर्क नहीं पड़ता कि आमतौर पर equals() विधियों null तर्कों से अवगत हैं।

+1

आप सही हैं कि प्रत्येक 'बराबर' विधि को जांचना चाहिए कि उसका * तर्क * शून्य है या नहीं। लेकिन यहां, भविष्यवाणी 'समान' विधि को 'शून्य' ऑब्जेक्ट पर कॉल करने का प्रयास कर सकती है, जिससे एनपीई हो जाता है – Marco13

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