Утверждение коллекции имеет несколько экземпляров элемента в Java?

Ответ на этот старый вопрос рекомендует Hamcrest для утверждения коллекций.

Что произойдет, если я захочу утверждать, что коллекция имеет несколько экземпляров объекта?

list = newArrayList();
list.add(1);
list.add(1);
list.add(2);
assertThat(list, hasItems(1, 2, 2)); // This should fail
assertThat(list, hasItems(1, 2, 1)); // This should pass

Код hamcrest, который я пробовал, не заботится о множественности - оба утверждения выше будут проходить.


person ripper234    schedule 08.02.2012    source источник


Ответы (6)


Самый простой метод, который я могу придумать, - это сначала отсортировать список, а затем использовать сравнение на равенство:

Collections.sort(list);

А потом:

assertEquals(Arrays.asList(1, 1, 2), list);
person Tomasz Nurkiewicz    schedule 08.02.2012

Multiset в Guava предназначен для эффективного отслеживания множественных вхождений элементов. .

Multiset<E> multiset = HashMultiset.create(collection);

и тогда у вас есть несколько вхождений x, если multiset.count(x) > 1.

person Louis Wasserman    schedule 08.02.2012

assertEquals(2, Collections.frequency(list, 1));
assertEquals(1, Collections.frequency(list, 2));

Конечно, вы можете использовать нотацию Hamcrest, если хотите.

И преимущество многократное по сравнению с некоторыми другими ответами: вы можете не быть владельцем коллекции, поэтому вы не можете контролировать, какую реализацию использовать. Кроме того, вы не ограничены типом коллекции (список, набор и т. д.), для которой можно использовать этот метод.

Спасибо за вопрос, иначе бы и не подумал :-)

person Kevin Welker    schedule 11.02.2012
comment
Перфекто. Минимум суеты, и пусть библиотеки JDK делают всю работу. - person pholser; 25.02.2012

Напишите сами еще одно утверждение. Это утверждение может использовать следующую технику:

  • скопировать коллекцию в новый список
  • для каждого элемента, который должен присутствовать, проверьте, есть ли он, и удалите его из списка
  • если вы хотите проверить, что экземпляров объекта больше нет, то для каждого элемента проверьте, что его больше нет в списке.
person JB Nizet    schedule 08.02.2012

Может быть, это только я, но похоже на HashMap твой друг. Я что-то пропустил?

person aviad    schedule 08.02.2012
comment
Может быть. Я ищу однострочник, который позволяет мне утверждать коллекции, соблюдая множественность. Конечно, я мог бы создать его, используя хэш-карту, но это не очень хороший ответ... он не дает никакой новой информации. «Создай сам» — это ответ по умолчанию, поэтому он не добавляет много информации. - person ripper234; 08.02.2012
comment
Я считаю, что мой ответ конструктивен, потому что, если популяция коллекции находится под вашим контролем, почему бы не выбрать подходящую коллекцию, которая соответствует цели? Если это не так (коллекция заполняется извне), я предлагаю вам перефразировать свой вопрос так, чтобы люди действительно могли понять, что вы ищете. - person aviad; 08.02.2012

Вы можете использовать Multimap Guava, который в основном представляет собой карту ключей -> список значений. В этом случае вам важен не столько список значений, сколько его размер. Вы должны создать следующую мультикарту из своего списка:

1 -> [1, 1]
2 -> [2]

Тогда ты можешь

Assert.assertEquals(2, map.get(1).size());

что гарантирует, что в вашем исходном списке есть ровно две «1».

Если вы не хотите зависеть от Guava, просто создайте карту каждого числа для его подсчета, что требует немного больше учета, но в целом все равно довольно просто.

person Cedric Beust    schedule 08.02.2012
comment
...Почему бы вам использовать это, а не Multiset? - person Louis Wasserman; 08.02.2012