जांचें कि क्या एक सूची में दूसरे से तत्व है


105

मेरे पास अलग-अलग वस्तुओं के साथ दो सूची हैं।

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

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

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

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

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

धन्यवाद!


सबसे पहले, जब आपने पाया = सही; तो बस तोड़; या पाश से बाहर आते हैं
jsist

stackoverflow.com/questions/5187888/… । इसके अलावा, तेजी से खोज के लिए बाइनरी सर्च का उपयोग करने की कोशिश करें और स्थिति को सूट करने के लिए अपने डीएस को बदल दें ...
jsist

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

@ Woot4Moo नहीं, वे नहीं
नेड

जवाबों:


220

यदि आपको मूल समानता का परीक्षण करने की आवश्यकता है, तो एक पंक्ति में इनपुट सूचियों को संशोधित किए बिना मूल JDK के साथ ऐसा किया जा सकता है

!Collections.disjoint(list1, list2);

यदि आपको किसी विशिष्ट संपत्ति का परीक्षण करने की आवश्यकता है, तो यह कठिन है। मैं डिफ़ॉल्ट रूप से सिफारिश करूंगा,

list1.stream()
   .map(Object1::getProperty)
   .anyMatch(
     list2.stream()
       .map(Object2::getProperty)
       .collect(toSet())
       ::contains)

... जो उपस्थिति के लिए list2प्रत्येक मान का परीक्षण करता है और प्रत्येक मान का परीक्षण करता है list1


1
क्या यह हमेशा गलत नहीं होगा क्योंकि दोनों अलग-अलग वस्तुएं हैं?
वेंकी

2
उम नहीं? दो संग्रह के बीच एक दूसरे के बराबर () नहीं होने पर परीक्षण का तिरस्कार करें।
लुई वासरमैन

13
इसके अलावा, कृपया ध्यान दें कि, सूचियों के लिए, यह O (n * m) होगा; आप अगर कर रहे हैं नकल करने के लिए तैयार list1एक में Setकी तुलना से पहले, आप हे (एन) + O (एम), है कि, हे (n + m) मिल जाएगा, कुछ अतिरिक्त रैम की कीमत पर; यह गति या स्मृति के बीच चयन की बात है।
१०:१० पर हैरोल्डो_क

यह केवल तभी काम करेगा जब "सूची <व्यक्ति> सूची 1; सूची <व्यक्ति> सूची 2" लेकिन सूची <व्यक्ति> सूची 1 जैसे दो अलग-अलग वस्तुओं या डेटाटिप्स पर नहीं; सूची <कर्मचारी> List2।
whoami

बेशक, यह उन परिदृश्यों @Zephyr के लिए काम नहीं करेगा, जो पूछे गए सवाल के लिए, यह तब तक सही काम करता है जब तक कि आपके पास सही समीकरण लागू होते हैं। यह सब मामला है!
सैयद सिराज उद्दीन

38

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

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

यह मानता है कि आपने अपने कस्टम ऑब्जेक्ट के लिए समान कार्यक्षमता को ठीक से अधिभारित किया है।


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

1
अपाचे कॉमन्स के लिए डाउनवोट जब एक jdk एकमात्र समाधान है
ओहिसीबी

9
@ohcibi जावा में एक लॉगर भी है, आपको लोगों को नीचे जाना चाहिए जो उस समय आपके पास होने पर Log4j और Log4j2 का उपयोग करने का सुझाव देते हैं।
वुट 4Moo

1
@ Woot4Moo यह निर्भर करता है। यदि ओपीएस समस्या को हल करने के लिए Log4j का उपयोग करने का कोई कारण है तो डाउनवोट होने का कोई कारण नहीं है। इस मामले में अपाचे कॉमन्स बस 99% जवाबों की तरह बेकार हो जाएगा जो अपाचे कॉमन्स का सुझाव देते हैं।
ओहिसी

1
@ मोहिनी लेकिन अगर आप पहले से ही अपाचे कॉमन्स का उपयोग कर रहे हैं तो यह वास्तव में ब्लोट नहीं है। यह एक अच्छा जवाब था।
vab2048

20

नरेंद्र के तर्क को छोटा करने के लिए, आप इसका उपयोग कर सकते हैं:

boolean var = lis1.stream().anyMatch(element -> list2.contains(element));

3
इस जवाब की सराहना की जा रही है।
केरवव

1
आप इसे थोड़ा और छोटा कर सकते हैं यदि आप चाहते हैं:list1.stream().anyMatch(list2::contains);
तारक

9

नहीं है एक विधि के Collectionनाम पर रखा गया retainAllहै, लेकिन कुछ होने दुष्प्रभाव आप के लिए संदर्भ

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

यह सच है कि कॉल के परिणामस्वरूप यह सूची बदल गई

यह पसंद है

boolean b = list1.retainAll(list2);

5

लोइस उत्तर सही है, मैं सिर्फ एक उदाहरण जोड़ना चाहता हूं:

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

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

2

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

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

  1. सभी वस्तुओं को एक सूची में एक HashSet में डालें (आपको ऑब्जेक्ट का उपयोग करने के लिए अपने द्वारा हैश फ़ंक्शन को लागू करना होगा ।AttributeSame ())

  2. अन्य सूची के माध्यम से जाओ और जाँच करें कि क्या कोई वस्तु हैशसेट में है।

इस तरह प्रत्येक वस्तु को एक बार में देखा जाता है। और HashSet O (1) में किसी भी ऑब्जेक्ट को जांचने या सम्मिलित करने के लिए पर्याप्त तेज़ है।


2

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

यदि यह सूची निर्दिष्ट तत्व है तो सही है। अधिक औपचारिक रूप से, यदि यह सूची केवल कम से कम एक तत्व ई जैसे (o == null; e == null: o.equals (e)) है तो सही है।

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

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


2

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

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

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


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

क्या O (n * m) से बेहतर कुछ नहीं है?
वूट ४Moo

.getAttributeSame ()?
मावे M

विधि getAttributeSame () के लिए ऑब्जेक्ट 1 और ऑब्जेक्ट 2 से कार्यान्वयन प्रदान नहीं किया गया है, लेकिन प्रश्न और उत्तर के लिए भी प्रासंगिक नहीं हैं; यह सिर्फ एक विशेषता देता है (विशेषता नाम, एक लंबा) जो दोनों वर्गों के पास है।
टॉम

0

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

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

सौभाग्य

संपादित: और मैं बराबरी से अधिक भार की सिफारिश नहीं करेंगे। इसका खतरनाक और संभवत: आपकी वस्तु के खिलाफ है।



0

साथ java 8में, हम जांच करने के लिए नीचे दिए गए की तरह कर सकते हैं अगर एक सूची अन्य सूची के किसी भी तत्व शामिल

boolean var = lis1.stream().filter(element -> list2.contains(element)).findFirst().isPresent();

0

यदि आप जाँच करना चाहते हैं कि क्या कोई तत्व सूची में मौजूद है, तो विधि का उपयोग करें।

if (list1.contains(Object o))
{
   //do this
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.