2012-08-03 24 views
70

से तत्व शामिल है या नहीं, मेरे पास अलग-अलग ऑब्जेक्ट्स के साथ दो सूचियां हैं।जांचें कि एक सूची में अन्य

List<Object1> list1; 
List<Object2> list2; 

मैं अगर List1 से तत्व List2 में मौजूद है, विशिष्ट विशेषता के आधार पर जाँच करना चाहते हैं (Object1 और Object2 है (दूसरों के बीच), के साथ प्रकार लांग), नामित attributeSame एक आपसी विशेषता()।

अभी, मैं इसे इस तरह कार्य करें:

boolean found = false; 
for(Object1 object1 : list1){ 
    for(Object2 object2: list2){ 
     if(object1.getAttributeSame() == object2.getAttributeSame()){ 
      found = true; 
      //also do something 
     } 
    } 
    if(!found){ 
     //do something 
    } 
    found = false; 
} 

लेकिन मुझे लगता है कि यह करने के लिए एक बेहतर और तेज तरीका :) कोई यह प्रस्ताव कर सकते हैं क्या है?

धन्यवाद!

+0

सबसे पहले, जब आप पाए गए = सत्य; तो बस तोड़ो; या लूप – Shubhansh

+0

http://stackoverflow.com/questions/5187888/java-searching-within-a-list-of-objects से बाहर आते हैं। इसके अलावा, तेजी से खोज के लिए बाइनरी खोज का उपयोग करने का प्रयास करें और स्थिति को सुइट करने के लिए अपने डीएस को बदलें ... – Shubhansh

+0

क्या वे ऑब्जेक्ट के अलावा एक आम माता-पिता साझा करते हैं? – Woot4Moo

उत्तर

143

यह एक पंक्ति में इनपुट सूचियों को संशोधित किए बिना बुनियादी JDK साथ किया जा सकता

!Collections.disjoint(list1, list2); 
+0

क्या यह हमेशा झूठी वापसी नहीं करेगा क्योंकि दोनों 2 अलग-अलग वस्तुएं हैं? – Venki

+1

उम, नहीं? यदि कोई ऑब्जेक्ट्स दो संग्रहों के बीच एक-दूसरे के बराबर नहीं हैं तो परीक्षणों को विघटित करें। –

+10

इसके अलावा, कृपया ध्यान दें कि, सूचियों के लिए, यह ओ (एन * एम) होगा; यदि आप तुलना करने से पहले 'सूची 1' को 'सेट' में कॉपी करने के इच्छुक हैं, तो आपको कुछ अतिरिक्त रैम की कीमत पर ओ (एन) + ओ (एम), ओ, एन (एम + एम) मिलेगा; यह गति या स्मृति के बीच चयन करने का मामला है। –

1

इसे तेज़ बनाने के लिए, आप एक ब्रेक जोड़ सकते हैं; कि जिस तरह से करता है, तो पाया सही पर सेट है पाश बंद हो जाएगा:

boolean found = false; 
for(Object1 object1 : list1){ 
    for(Object2 object2: list2){ 
     if(object1.getAttributeSame() == object2.getAttributeSame()){ 
      found = true; 
      //also do something 
      break; 
     } 
    } 
    if(!found){ 
     //do something 
    } 
    found = false; 
} 

आप अगर वहाँ एक इसी के साथ कुंजी के रूप में attributeSame, आप तेजी से एक मूल्य के लिए एक नक्शे में जांच कर सकता है सूचियों में से जगह में नक्शे के लिए होता है, तो दूसरे मानचित्र में मूल्य या नहीं।

+0

हाय टॉम, ध्यान देने के लिए धन्यवाद! हाँ, टाइप करते समय मैं "ब्रेक" भूल गया। लेकिन मैं सोच रहा था कि कुछ एल्गोरिदम है, या मुझे इन सूचियों को किसी अन्य संग्रह में बदलना चाहिए। – Ned

+0

मैंने आपकी टिप्पणी का जवाब देने के लिए एक संपादन किया – Tom

+0

ओ (एन * एम) से बेहतर कुछ भी नहीं है? – Woot4Moo

2

.contains(Object obj) के लिए JavaDoc के अनुसार:

रिटर्न सच अगर इस सूची निर्दिष्ट तत्व शामिल है। औपचारिक रूप से औपचारिक रूप से, सत्य लौटाता है अगर केवल इस सूची में कम से कम एक तत्व ई है (जैसे = o == null? E == null: o.equals (e))।

इसलिए यदि आप अपने दिए गए ऑब्जेक्ट के लिए अपने .equals() विधि ओवरराइड, आप ऐसा करने में सक्षम होना चाहिए: if(list1.contains(object2))...

तत्वों अनूठा हो जाएगा (। यानी अलग-अलग विशेषताओं है) आप .equals() और .hashcode() रद्द कर सकते थे और HashSets में सबकुछ स्टोर करें। यह आपको यह जांचने की अनुमति देगा कि इसमें निरंतर समय में कोई अन्य तत्व है या नहीं।

26

आप Apache Commons CollectionUtils उपयोग कर सकते हैं:

if(CollectionUtils.containsAny(list1,list2)) { 
    // do whatever you want 
} else { 
    // do other thing 
} 

मतलब यह है कि आप ठीक ढंग से अपने कस्टम वस्तुओं के लिए बराबर कार्यक्षमता अतिभारित है।

+0

मृत झुकाव, दोस्त। – alexander

+7

यह 4 साल हो गया है और मैं स्पष्ट रूप से पैकेज और फ़ंक्शन को भी कॉल करता हूं। – Woot4Moo

+0

अपाचे कॉमन्स के लिए डाउनवोट जब कोई जेडीके केवल समाधान – ohcibi

2

तेज तरीके से अतिरिक्त स्थान की आवश्यकता होगी।

उदाहरण के लिए:

  1. एक HashSet में एक सूची में सभी आइटम डाल

  2. अन्य के माध्यम से जाओ (आप खुद ही हैश समारोह को लागू करने के object.getAttributeSame() का उपयोग करने के लिए है) सूचीबद्ध करें और जांचें कि कोई आइटम हैशसेट में है या नहीं।

इस तरह प्रत्येक ऑब्जेक्ट का सबसे अधिक बार दौरा किया जाता है। और हैशसेट ओ (1) में किसी ऑब्जेक्ट को चेक या डालने के लिए पर्याप्त तेज़ है।

8

वहाँ एक विधि Collection नामित retainAll की लेकिन आप reference

इस सूची में केवल तत्वों कि निर्दिष्ट संग्रह (वैकल्पिक आपरेशन) में निहित हैं बरकरार रखे कुछ दुष्प्रभाव चल रहा है। दूसरे शब्दों में, इस सूची से निर्दिष्ट संग्रह में शामिल नहीं हैं, इस सूची से हटा देता है।

सच अगर इस सूची कॉल की वजह से बदल

इसके

boolean b = list1.retainAll(list2); 
0

तरह आप डेटा के प्रकार के पकड़ को परिभाषित कर सकते हैं? क्या यह बड़ा डेटा है? क्या यह क्रमबद्ध है? मुझे लगता है कि आपको डेटा के आधार पर विभिन्न दक्षता दृष्टिकोणों पर विचार करने की आवश्यकता है।

उदाहरण के लिए, यदि आपका डेटा बड़ा और अपरिवर्तित है, तो आप इंडेक्स द्वारा दोनों सूचियों को एक साथ जोड़कर फिर से चालू कर सकते हैं और प्रत्येक सूची विशेषता में प्रत्येक सूची विशेषता को स्टोर कर सकते हैं। तो आप सहायक सूची में वर्तमान विशेषताओं द्वारा चेक पार कर सकते हैं।

सौभाग्य

संपादित: और मैं बराबर ओवरलोडिंग की सिफारिश नहीं होगा। इसका खतरनाक और शायद आपके ऑब्जेक्ट ओप अर्थ के खिलाफ।

2

Loius जवाब सही है, मैं सिर्फ एक उदाहरण जोड़ना चाहते हैं:

listOne.add("A"); 
listOne.add("B"); 
listOne.add("C"); 

listTwo.add("D"); 
listTwo.add("E"); 
listTwo.add("F");  

boolean noElementsInCommon = Collections.disjoint(listOne, listTwo); // true 
+0

मुझे लगता है कि यदि आप दूसरी सूची सूची में तत्व 'ए' जोड़ते हैं तो दो .add ("ए"); भले ही Collections.disjoint (listOne, listTwo); सच आता है। –