2012-02-08 143 views
2

this old question的回答建议Hamcrest对集合进行断言。断言一个集合在Java中有多个项目实例?

如果我想断言一个集合有多个对象实例会发生什么?

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代码并不在乎多重性 - 上面的断言都会通过。

回答

0

我能想到的最简单的方法是先排序列表,然后用平等的比较:

Collections.sort(list); 

然后:

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

我会接受这个,直到有更好的东西出现,谢谢。 – ripper234 2012-02-08 09:58:53

0

自己写一个断言。这种说法可以使用以下方法:

  • 副本收集到一个新的列表
  • 对于必须存在于每个元素,测试,如果是这样,如果你想从列表
  • 删除检查一个对象没有更多的实例,然后对每个元素测试它不在列表中。
0

也许这只是我,但看起来像HashMap是你的朋友。我想念什么?

+1

也许。我正在寻找一种能够让我坚持收藏的单行书,尊重多样性。当然,我可以*使用hashmap *构建一个,但这不是一个好的答案......它不提供任何新的信息。 “自己构建”是默认的答案,所以它不会添加太多信息。 – ripper234 2012-02-08 08:28:03

+0

我相信我的回答是有建设性的,因为如果收集人口在你的控制之下,为什么不选择适合目的的适当收藏?如果这不是这种情况(集合是外部填充的),我建议你以某种方式改写你的问题,人们可以真正理解你在找什么。 – aviad 2012-02-08 09:47:54

0

您可以使用番石榴的Multimap之,这基本上是一个地图键 - >值列表。在这种情况下,你不关心值的列表,但它的大小。你会从你的列表创建以下多重映射:

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

然后你可以

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

这可以确保恰好有两个“1”“在你原来的列表中。

如果你不想依靠番石榴,只需创建一个每个数字的地图到它的计数,这需要更多的簿记,但总体上仍然非常简单。

+0

...为什么你会用这个,而不是'Multiset'? – 2012-02-08 18:44:35

+0

Doh,当然,我在想什么...... – 2012-02-08 23:26:02

2

番石榴的Multiset旨在有效地跟踪元素的多次出现。

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

,然后你如果multiset.count(x) > 1x多次出现。

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

当然,如果你愿意,你可以使用Hamcrest符号。

这个优点在一些其他答案中是多方面的:您可能不是集合的所有者,因此您可能无法控制要使用的实现。此外,您不限于可以使用此技术的集合类型(列表,集合等)。

感谢您的问题,我不会想到这个,否则:-)

+0

Perfecto。最小的麻烦,并让JDK库来完成这项工作。 – pholser 2012-02-24 21:32:13

相关问题