जावा सेट के लिए 'सम्‍मिलित' जैसा कुछ है?


307

मेरे पास दो सेट हैं, ए और बी, एक ही प्रकार के।

मुझे यह पता लगाना है कि क्या ए में सेट बी से कोई तत्व है।

क्या यह सबसे अच्छा तरीका है कि सेट पर पुनरावृत्ति के बिना होगा? सेट लाइब्रेरी में contains(object)और है containsAll(collection), लेकिन नहीं containsAny(collection)


4
क्या आप दक्षता कारणों से या कोड स्वच्छता के लिए चलने से बचने की कोशिश कर रहे हैं?
यशवित

जवाबों:


527

Collections.disjoint(A, B)काम नहीं करेगा ? प्रलेखन से:

trueयदि दो निर्दिष्ट संग्रह में कोई तत्व सामान्य नहीं है, तो लौटाता है ।

इस प्रकार, विधि वापस आ जाती है falseयदि संग्रह में कोई सामान्य तत्व होते हैं।


17
इसे अन्य समाधानों के लिए प्राथमिकता दें क्योंकि यह या तो सेट को संशोधित नहीं करता है या एक नया बनाता है।
devconsole

7
और मानक JRE है, और किसी भी संग्रह के साथ काम करता है, न कि केवल सेट।
पियरे हेनरी

4
मुझे नहीं लगता कि यह गतिमान है, यह शॉर्ट-सर्किट नहीं होगा जब चौराहे का पहला तत्व पाया जाता है।
बेन हॉर्नर

7
वास्तव में जैसे ही यह शॉर्ट सर्किट होगा, जैसे ही यह पहला सामान्य तत्व है
Xipo


156

Stream::anyMatch

जावा 8 के बाद से आप उपयोग कर सकते हैं Stream::anyMatch

setA.stream().anyMatch(setB::contains)

1
यही वह है जिसकी तलाश में मैं हूं! धन्यवाद :-) मुझे यह भी नहीं पता था कि आप चर का उपयोग कर सकते हैं :: वाक्य रचना!
डेन्स्टन

1
@blevert, क्या आप बता सकते हैं कि किसी भी मैच के अंदर क्या होता है?
क्रिस्टियानो

7
@ क्रिस्टियानो यहाँ, anyMatchउन सभी तत्वों को स्ट्रीम करेगा setAऔर setB.contains()उन सभी को कॉल करेगा। यदि किसी भी तत्व के लिए "सही" लौटाया जाता है, तो एक पूरे के रूप में अभिव्यक्ति सही का मूल्यांकन करेगी। आशा है कि इससे मदद मिली।
एलेक्स वुलज


31

लागू करने के लिए एक अच्छा तरीका है सेट के लिए किसी भी अमरूद सेट का उपयोग कर रहा है। सर्दियों () । ।

containsAnyएक वापस करेगा boolean, इसलिए कॉल ऐसा दिखता है:

Sets.intersection(set1, set2).isEmpty()

यह सही है अगर सेट असंतुष्ट हैं, अन्यथा झूठे हैं। इस की समय जटिलता, रिटेल से थोड़ी बेहतर है, क्योंकि आपको अपने मूल सेट को संशोधित करने से बचने के लिए कोई क्लोनिंग करने की आवश्यकता नहीं है।


3
इस दृष्टिकोण का उपयोग करने का एकमात्र नुकसान आपको अमरूद पुस्तकालयों को शामिल करना है। जो मुझे लगता है कि नुकसान नहीं है क्योंकि Google संग्रह API बहुत मजबूत हैं।
मोहम्मद अदनान

इस डेटा सहित अमरूद कलेक्शंस यूटिलिटी फ़ंक्शंस के अधिकांश डेटाडियर, डेटा संरचनाओं के विचार लौटाते हैं । तो इस मामले में चिंता करने के लिए "सेट का निर्माण" नहीं है। कार्यान्वयन यहां पढ़ने के लिए दिलचस्प है, और / या javadoc देखें: google.github.io/guava/releases/21.0/api/docs/com/google/common/…
chut

@ मोहम्मद अदनान एक और नुकसान यह है कि यह पूर्ण चौराहे की गणना करता है - अगर सेट 1 और सेट 2 बहुत बड़े हैं, तो यह सामान्य रूप से किसी भी चीज की जांच करने की तुलना में बहुत अधिक संसाधन गहन (सीपीयू और मेमोरी वार दोनों) होगा।
मार्क्स


16

मैं org.apache.commons.collections.CollectionUtils का उपयोग करता हूं

CollectionUtils.containsAny(someCollection1, someCollection2)

वह सब है! सच लौटाता है अगर कम से कम एक तत्व दोनों संग्रहों में है।

उपयोग करने के लिए सरल है, और फ़ंक्शन का नाम अधिक विचारोत्तेजक है।


5

retainAll()सेट इंटरफ़ेस में उपयोग करें । यह विधि दोनों सेटों में आम तत्वों का प्रतिच्छेदन प्रदान करती है। अधिक जानकारी के लिए एपीआई डॉक्स देखें।


यदि पुनरावृत्ति से बचने का बिंदु दक्षता के लिए है, तो retainAllशायद मदद नहीं करेगा। AbstractCollectionपुनरावृत्तियों में इसका कार्यान्वयन ।
यशवित

1
yshavit सही है। यह देखते हुए कि ओपी यह देखना चाहता है कि दोनों सेटों में कोई तत्व मौजूद है या नहीं, एक उचित एल्गोरिथ्म O(1)का सबसे अच्छा मामले में चलने का समय retainAllहोगा , जबकि एक की तर्ज पर कुछ O(N)होगा (यह केवल 1 सेट के आकार पर निर्भर करेगा) सबसे अच्छा समय चल रहा है।
ज़ेचिन

3

मैं एक HashMapसेट ए से बनाने की सिफारिश करूंगा , और फिर सेट बी के माध्यम से पुनरावृत्ति करना और यह जांचना कि बी का कोई तत्व ए में है। यह O(|A|+|B|)समय में चलेगा (क्योंकि कोई टक्कर नहीं होगी), जबकि समय retainAll(Collection<?> c)में चलना चाहिए O(|A|*|B|)


3

ऐसा करने के लिए थोड़ा कठिन तरीका है। यदि और केवल तभी A सेट में कॉल की तुलना में कुछ B का तत्व होता है

A.removeAll(B)

ए सेट को संशोधित करेगा। इस स्थिति में निष्कासन सही हो जाएगा (जैसा कि निष्कासन डॉक्स में बताया गया है )। लेकिन शायद आप ए सेट को संशोधित नहीं करना चाहते हैं, इसलिए आप इस तरह से एक कॉपी पर कार्रवाई करने के लिए सोच सकते हैं:

new HashSet(A).removeAll(B)

और यदि सेट अलग-अलग नहीं हैं तो रिटर्निंग वैल्यू सही होगी, क्योंकि उनके पास गैर-खाली चौराहा है।

अपाचे कॉमन्स कलेक्शंस भी देखें


2

आप रिटेल विधि का उपयोग कर सकते हैं और अपने दो सेटों का प्रतिच्छेदन प्राप्त कर सकते हैं ।


ज्यादातर मामलों में किसी को मूल सेट रखने की आवश्यकता होती है, इसलिए उपयोग retainAllकरने के लिए मूल सेट की एक प्रति बनाना आवश्यक है। फिर यह ZéychinHashSet द्वारा सुझाए अनुसार उपयोग करने के लिए अधिक कुशल है ।
पेट्र पुडलक

यह एक राज्य परिवर्तन है, स्थिति की जांच नहीं
बेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.