2009-10-14 3 views
31

Я искал метод, который работает как Arrays.equals(a1, a2), но игнорирует порядок элементов. Я не смог найти его в Google Collections (что-то вроде Iterables.elementsEqual(), но это делает заказ для заказа), а JUnit (assertEquals(), очевидно, просто вызывает equals() в коллекции, что зависит от реализации Collection, и это не то, что я хочу) Было бы лучше, если бы такой метод принимал Iterable с, но я тоже в порядке, просто принимая Collection s Такой метод, конечно, учитывал бы любые повторяющиеся элементы в коллекции (поэтому он не может просто протестировать для containsAll()).Есть ли способ проверить, содержат ли две коллекции одни и те же элементы, независимо от порядка?

Обратите внимание, что я не спрашиваю, как реализовать такую ​​вещь, мне просто интересно, есть ли в ней библиотека стандартных коллекций.

ответ

39

Apache Commons-коллекции имеет CollectionUtils#isEqualCollection:

Возвращает истину, если данные коллекции содержат одни и те же элементы, с точно такой же мощности.

То есть, если мощность e в a равна мощности e в b для каждого элемента e в a или b.

Что, я думаю, именно то, что вам нужно.

+21

В случае, если вы не хотите использовать Apache (или вы не можете), вы всегда можете сделать: collection1.containsAll (collection2) && collection2.containsAll (collection1) –

+25

@ChrisGonzales, остерегайтесь этого решения - оно вернет true для следующие две коллекции: collection1 = [1, blah, 1, 4], collection2 = [1, blah, blah, 4]. Там, где эти две коллекции действительно не совпадают. –

2

Если вы хотите игнорировать порядок, то как насчет наборов тестов для равенства?

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

Это не работает, потому что это будет выбросить дублирующие элементы. Кроме того, мне пришлось бы создать два новых HashSets. Я бы предпочел не создавать для этого новые объекты. – Jorn

+0

Это нормально, если вам не нужны дубликаты, например. c1 = Arrays.asList (1, 1, 2), c2 = Arrays.asList (1, 2, 2) будут равны в соответствии с этим выражением. – finnw

+2

Верно, но мне все равно, что дубликаты (как теперь говорит вопрос) – Jorn

27

Это три вызовы методов и использует Google КоллекцииGuava, но, возможно, так же просто, как он получает:

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

Создание временных Multiset сек может показаться расточительным, но сравнивать коллекции вам нужно как-то их индексировать.

+0

Это, кажется, самое эффективное (и простое) решение, которое я видел до сих пор. – Jorn

+0

@Jorn: Я думал, вы сказали, что не спрашиваете, как реализовать это ... –

+0

Я не говорю, что это решение, которое я просил, но я не видел ответа, который предоставляет мне один вызов метода сделай это. – Jorn