2009-10-14 9 views
31

Szukałem metody działającej jak Arrays.equals(a1, a2), ale ignorując kolejność elementów. Nie udało mi się go znaleźć ani w kolekcjach Google (coś w stylu Iterables.elementsEqual(), ale to powoduje zamówienie) i JUnit (assertEquals() oczywiście po prostu wywołuje equals() w kolekcji, co zależy od implementacji kolekcji, i to nie jest to, co chcę) Najlepiej byłoby, gdyby taka metoda zajęłaby Iterable s, ale nie przeszkadza mi również po prostu przyjmowanie Collection s Taka metoda oczywiście bierze pod uwagę wszystkie duplikaty elementów w kolekcji (więc nie może po prostu przetestować dla containsAll()).Czy istnieje sposób sprawdzenia, czy dwie kolekcje zawierają te same elementy, niezależnie od kolejności?

Zauważ, że nie pytam, jak zaimplementować takie rzeczy, zastanawiałem się tylko, czy któreś ze standardowych bibliotek kolekcji je ma.

Odpowiedz

39

Apache Commons-kolekcje ma CollectionUtils#isEqualCollection:

Zwraca TRUE jeśli podane Kolekcje zawierają dokładnie te same elementy z dokładnie tej samej liczności.

Oznacza to, że jeśli liczebność e w a jest równa liczności e w b, dla każdego elementu e w a lub b.

Który jest, myślę, dokładnie to, czego szukasz.

+21

Jeśli nie chcesz używać Apache (lub nie możesz), zawsze możesz: collection1.containsAll (collection2) && collection2.containsAll (collection1) –

+25

@ChrisGonzales, strzeż się tego rozwiązania - zwróci true dla następujące dwie kolekcje: collection1 = [1, bla, 1, 4], collection2 = [1, bla, bla, 4]. Gdzie te dwie kolekcje rzeczywiście nie są takie same. –

2

Jeśli chcesz zignorować zamówienie, to co z testowaniem zestawów dla równości?

new HashSet(c1).equals(new HashSet(c2)) 
+2

To nie działa, ponieważ wyrzuciłoby duplikaty elementów. Ponadto, musiałbym utworzyć dwa nowe HashSets. Wolałbym raczej unikać tworzenia nowych obiektów. – Jorn

+0

Jest to dobre, jeśli nie interesują Cię duplikaty, np. c1 = Arrays.asList (1, 1, 2), c2 = Arrays.asList (1, 2, 2) będą równe zgodnie z tym wyrażeniem. – finnw

+2

To prawda, ale zależy mi na duplikatach (jak to teraz również stanowi pytanie). – Jorn

27

To trzy wywołania metod i wykorzystuje kolekcje GoogleGuava, ale to prawdopodobnie tak proste, jak to robi:

HashMultiset.create(c1).equals(HashMultiset.create(c2)); 

Tworzenie tymczasowych Multiset s może wydawać marnotrawstwem, ale porównać kolekcje sprawnie trzeba je jakoś zindeksować.

+0

To wydaje się być najbardziej wydajnym (i prostym) rozwiązaniem, które do tej pory widziałem. – Jorn

+0

@Jorn: Myślałem, że powiedziałeś, że nie pytasz, jak to zaimplementować ... –

+0

Nie mówię, że jest to rozwiązanie, o które prosiłem, ale nie widziałem odpowiedzi, która zapewnia mi pojedyncze wywołanie metody Zrób to. – Jorn