ripper234
ripper234

Reputation: 230008

Asserting a collection has multiple instances of an item in Java?

The answer to this old question recommends Hamcrest for asserting on collections.

What happens if I want to assert a collection has multiple instances of an object?

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

The hamcrest code I tried does not care about multiplicity - both asserts above will pass.

Upvotes: 2

Views: 2175

Answers (6)

Kevin Welker
Kevin Welker

Reputation: 7937

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

Of course you could use Hamcrest notation on this if you want.

And the advantage is multi-fold over some other answers: you may not be the owner of the collection so you may not have control over what implementation to use. And furthermore, you are not restricted to the type of Collection (List, Set, etc.) that this technique can be used on.

Thanks for the question, I wouldn't have thought of this otherwise :-)

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198023

Guava's Multiset is intended to efficiently keep track of multiple occurrences of elements.

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

and then you have multiple occurrences of x if multiset.count(x) > 1.

Upvotes: 2

Cedric Beust
Cedric Beust

Reputation: 15608

You can use Guava's Multimap, which is basically a map of keys -> list of values. In this case, you don't care so much about the list of values but its size. You would create the following multimap from your list:

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

Then you can

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

which makes sure that there are exactly two "1"'s in your original list.

If you don't want to depend on Guava, simply create a Map of each number to its count, which requires a bit more bookkeeping, but still pretty simple overall.

Upvotes: 0

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340693

The easiest technique I can think of is sorting the list first and then using equality comparison:

Collections.sort(list);

And then:

assertEquals(Arrays.asList(1, 1, 2), list);

Upvotes: 0

aviad
aviad

Reputation: 8278

Maybe it is just me but seems like HashMap is your friend. Do I miss something?

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691645

Write another assertion yourself. This assertion could use the following technique:

  • copy the collection to a new list
  • for each element that must be present, test if it is, and remove it from the list
  • if you want to check that there aren't more instances of an object, then for each element, test that it isn't in the list anymore.

Upvotes: 0

Related Questions