दो सेटों के बीच अंतर प्राप्त करना


161

इसलिए अगर मेरे पास दो सेट हैं:

Set<Integer> test1 = new HashSet<Integer>();
test1.add(1);
test1.add(2);
test1.add(3);

Set<Integer> test2 = new HashSet<Integer>();
test2.add(1);
test2.add(2);
test2.add(3);
test2.add(4);
test2.add(5);

क्या उनकी तुलना करने का एक तरीका है और केवल 4 और 5 का एक सेट है?


के संभावित डुप्लिकेट stackoverflow.com/questions/8064570/...
सचिन थापा

11
यह एक सटीक डुप्लिकेट नहीं है: सममित अंतर और अंतर समान नहीं हैं।
साइमन निकर्सन

यदि test1निहित है 6, तो उत्तर 4,5,6 होगा? यानी क्या आप सममित अंतर चाहते हैं en.wikipedia.org/wiki/Symmetric_difference
कॉलिन डी

1
अगर test1 में 6 होते हैं, तो मैं चाहता हूं कि उत्तर अभी भी 4, 5.
डेविड ट्यूनेल

जवाबों:


197

इसे इस्तेमाल करे

test2.removeAll(test1);

सेट # removeAll

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


43
यह काम करेगा, लेकिन मुझे लगता है कि सेट ऑपरेशन जैसे कि यूनियन में अंतर, जावा में बनाया गया एक अच्छा फीचर होगा। उपरोक्त समाधान सेट को संशोधित करेगा, कई स्थितियों में हम वास्तव में ऐसा नहीं चाहते हैं।
प्रवीण कुमार

129
कैसे जावा इस डेटा संरचना को कॉल करने के लिए पित्त Setहो सकता है जब यह परिभाषित नहीं करता है union, intersectionया difference!!!
जेम्स न्यूमैन

10
यह समाधान पूरी तरह से सही नहीं है। क्योंकि टेस्ट 1 और टेस्ट 2 के क्रम में फर्क होता है।
बोजान पेटकोविक

1
चाहेंगे test1.removeAll(test2);के रूप में एक ही परिणाम वापसी test2.removeAll(test1);?
डेटव

3
@datv परिणाम भिन्न होगा। test1.removeAll(test2)एक खाली सेट है। test2.removeAll(test1)है {4, 5}
मौनव्रत

122

यदि आप अमरूद (पूर्व Google संग्रह) लायब्रेरी का उपयोग करते हैं तो एक समाधान है:

SetView<Number> difference = com.google.common.collect.Sets.difference(test2, test1);

लौटा SetViewएक है Set, यह एक जीवित प्रतिनिधित्व है जिसे आप या तो अपरिवर्तनीय बना सकते हैं या दूसरे सेट में कॉपी कर सकते हैं। test1और test2बरकरार हैं।


6
ध्यान दें कि test2 और test1 का क्रम मायने रखता है। वहाँ भी समरूपता () जहां आदेश कोई फर्क नहीं पड़ता।

1
symmetricDifference()चौराहे पर सभी लाएंगे, लेकिन यह मूल प्रश्न नहीं है।
एलनजे

16

हाँ:

test2.removeAll(test1)

यद्यपि यह परिवर्तन करेगा test2, इसलिए यदि आपको इसे संरक्षित करने की आवश्यकता है तो एक प्रति बनाएँ।

इसके अलावा, आप शायद के <Integer>बजाय मतलब था <int>


7

जावा 8

हम हटाने का उपयोग कर सकते हैं जो एक उपयोगिता विधि लिखने के लिए एक विधेय लेता है:

// computes the difference without modifying the sets
public static <T> Set<T> differenceJava8(final Set<T> setOne, final Set<T> setTwo) {
     Set<T> result = new HashSet<T>(setOne);
     result.removeIf(setTwo::contains);
     return result;
}

और यदि हम अभी भी कुछ पूर्व संस्करण में हैं, तो हम removeAll का उपयोग कर सकते हैं:

public static <T> Set<T> difference(final Set<T> setOne, final Set<T> setTwo) {
     Set<T> result = new HashSet<T>(setOne);
     result.removeAll(setTwo);
     return result;
}

3

यदि आप जावा 8 का उपयोग कर रहे हैं, तो आप कुछ इस तरह की कोशिश कर सकते हैं:

public Set<Number> difference(final Set<Number> set1, final Set<Number> set2){
    final Set<Number> larger = set1.size() > set2.size() ? set1 : set2;
    final Set<Number> smaller = larger.equals(set1) ? set2 : set1;
    return larger.stream().filter(n -> !smaller.contains(n)).collect(Collectors.toSet());
}

4
@Downvoter: शायद आप यह महसूस करने में विफल रहे हैं कि अन्य उत्तर यह देखने के लिए जांच नहीं करते हैं कि कौन Setबड़ा है ... इसलिए, यदि आप Setकिसी बड़े से छोटे को निकालने की कोशिश कर रहे हैं, तो आपको Setअलग-अलग परिणाम प्राप्त होंगे।
जोश एम।

40
आप मान रहे हैं कि उस फ़ंक्शन का उपभोक्ता हमेशा छोटे सेट को घटाना चाहता है। सेट अंतर एंटीकोमेटिक ( en.wikipedia.org/wiki/Anticommutativity ) है। एबी! = बीए
साइमन

7
अंतर के बावजूद कि आप किस अंतर को लागू करते हैं, मैं public static <T> Set<T> difference(final Set<T> set1, final Set<T> set2) {हस्ताक्षर के रूप में उपयोग करूंगा , फिर विधि सामान्य उपयोगिता फ़ंक्शन के रूप में उपयोग करने योग्य है।
kap

1
@kap, लेकिन फिर एक जोड़ें Comparator<T>तुलना करने में सक्षम होने के लिए क्योंकि equalsहमेशा पर्याप्त नहीं है।

6
इससे अप्रत्याशित परिणाम प्राप्त होंगे क्योंकि अंतर ऑपरेशन का क्रम उपयोगकर्ता को जागरूक किए बिना स्विच किया जा सकता है। एक छोटे सेट से बड़े सेट का घटाव गणितीय रूप से अच्छी तरह से परिभाषित है और इसके लिए उपयोग के बहुत सारे मामले हैं।
जोएल कॉर्नेट

3

आप CollectionUtils.disjunctionसभी अंतर प्राप्त करने या CollectionUtils.subtractपहले संग्रह में अंतर प्राप्त करने के लिए उपयोग कर सकते हैं ।

यहाँ एक उदाहरण है कि कैसे करना है:

    var collection1 = List.of(1, 2, 3, 4, 5);
    var collection2 = List.of(2, 3, 5, 6);
    System.out.println(StringUtils.join(collection1, " , "));
    System.out.println(StringUtils.join(collection2, " , "));
    System.out.println(StringUtils.join(CollectionUtils.subtract(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.retainAll(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.collate(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.disjunction(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.intersection(collection1, collection2), " , "));
    System.out.println(StringUtils.join(CollectionUtils.union(collection1, collection2), " , "));

3
किस परियोजना CollectionUtilsसे आता है? क्या 1 को यह मानना ​​है कि यह अपाचे कॉमन्स कलेक्शन से है?
बुहके सिंडी

0

केवल एक उदाहरण यहाँ रखने के लिए (सिस्टम में है existingState, और हम तत्वों को निकालने के लिए तत्वों को खोजना चाहते हैं (तत्व जो newStateइसमें मौजूद नहीं हैं existingState) और तत्वों को जोड़ने के लिए (ऐसे तत्व जो newStateमौजूद नहीं हैं existingState):

public class AddAndRemove {

  static Set<Integer> existingState = Set.of(1,2,3,4,5);
  static Set<Integer> newState = Set.of(0,5,2,11,3,99);

  public static void main(String[] args) {

    Set<Integer> add = new HashSet<>(newState);
    add.removeAll(existingState);

    System.out.println("Elements to add : " + add);

    Set<Integer> remove = new HashSet<>(existingState);
    remove.removeAll(newState);

    System.out.println("Elements to remove : " + remove);

  }
}

परिणामस्वरूप यह उत्पादन करेगा:

Elements to add : [0, 99, 11]
Elements to remove : [1, 4]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.