2013-09-05 19 views
80

Więc jeśli mam dwa zestawy:Pierwsze różnica pomiędzy dwoma zestawami

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

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

czy jest jakiś sposób, aby je porównać i mają tylko zestaw 4 i 5 zwrócony?

+0

Możliwe duplikaty http://stackoverflow.com/questions/8064570/what-is-the-best-way-get-symmetric-difference-between-two-sets-in-java –

+9

To nie jest dokładny duplikat: symetryczna różnica i różnica nie są takie same. –

+0

Jeśli "test1" zawierał "6", czy odpowiedź byłaby 4,5,6? tzn. czy chcesz symetrycznej różnicy http://en.wikipedia.org/wiki/Symmetric_difference –

Odpowiedz

110

Spróbuj

test2.removeAll(test1); 

Set#removeAll

Usuwa z tego zbioru wszystkich jego elementów, które są zawarte w określonej kolekcji (opcja pracy). Jeśli określona kolekcja jest również zbiorem, ta operacja efektywnie modyfikuje ten zbiór, tak aby jego wartość stanowiła asymetryczną różnicę zestawu dwóch zestawów.

+20

To zadziała, ale myślę, że byłoby miło funkcja do ustawiania operacji takich jak union, różnica wbudowana w java. Powyższe rozwiązanie zmodyfikuje zestaw, w wielu sytuacjach tak naprawdę tego nie chcemy. –

+41

W jaki sposób Java może nazywać tę strukturę danych "zestawem", gdy nie definiuje "unii", "przecięcia" lub "różnicy" !!! –

+6

To rozwiązanie nie jest w pełni poprawne. Ponieważ kolejność test1 i test2 robi różnicę. –

11

Tak:

test2.removeAll(test1) 

Chociaż ta będzie mutować test2, więc utworzyć kopię, jeśli chcesz go zachować.

Co więcej, prawdopodobnie miałeś na myśli <Integer> zamiast <int>.

5

Jeśli używasz Java 8, można spróbować czegoś takiego:

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

@Dvvoter: Być może nie zdawałeś sobie sprawy z tego, że inne odpowiedzi nie sprawdzają, który "Set" jest większy ... Dlatego, jeśli próbujesz odjąć mniejszy "Set" z większego "Setu", ty otrzymają różne wyniki. –

+20

zakładasz, że konsument tej funkcji zawsze chce odjąć mniejszy zestaw. Ustawiona różnica jest antysprzężeniowa (http://en.wikipedia.org/wiki/Anticommutativity). A-B!= B-A – Simon

+5

Bez względu na to, jaki wariant różnicy zastosujesz, użyłbym 'public static Set różnicy (ostateczny Set set1, final Set set2) {' jako podpis, metoda jest następnie użyteczna jako ogólna funkcja użyteczności. – kap

71

Jeśli używasz Guava (dawne kolekcje Google) biblioteka istnieje rozwiązanie:

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

zwrócony SetView jest Set, jest to reprezentacja na żywo, którą możesz albo uczynić niezmienną, albo skopiować do innego zestawu. test1 i test2 pozostają nienaruszone.

+0

Należy zauważyć, że [zamówienie] (https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Sets.html#difference (java.util.Set,% 20java .util.Set)) z test2 i test1 ma znaczenie. Istnieje również [symmetricDifference()] (https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Sets.html#symmetricDifference (java.util.Set,% 20java.util.Set)), w którym zamówienie nie ma znaczenia. – datv

Powiązane problemy