[COLLECTIONS-429] Fix containsAll in case coll2 contains the same value multiple times.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1440453 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c2b58d4ac7
commit
6516216f09
|
@ -71,6 +71,14 @@ public class CollectionUtils {
|
|||
return getFreq(obj, cardinalityB);
|
||||
}
|
||||
|
||||
public int sizeA() {
|
||||
return cardinalityA.size();
|
||||
}
|
||||
|
||||
public int sizeB() {
|
||||
return cardinalityB.size();
|
||||
}
|
||||
|
||||
private final int getFreq(final Object obj, final Map<?, Integer> freqMap) {
|
||||
final Integer count = freqMap.get(obj);
|
||||
if (count != null) {
|
||||
|
@ -284,11 +292,13 @@ public class CollectionUtils {
|
|||
|
||||
/**
|
||||
* Returns <code>true</code> iff all elements of {@code coll2} are also contained
|
||||
* in {@code coll1}.
|
||||
* in {@code coll1}. The cardinality of values in {@code coll2} is not taken into account,
|
||||
* which is the same behavior as {@link Collection#containsAll(Collection)}.
|
||||
* <p>
|
||||
* In other words, this method returns <code>true</code> iff the
|
||||
* {@link #intersection} of <i>coll1</i> and <i>coll2</i> has the same cardinality as
|
||||
* {@code coll2}. In case {@code coll2} is empty, {@code true} will be returned.
|
||||
* the set of unique values from {@code coll2}. In case {@code coll2} is empty, {@code true}
|
||||
* will be returned.
|
||||
* <p>
|
||||
* This method is intended as a replacement for {@link Collection#containsAll(Collection)}
|
||||
* with a guaranteed runtime complexity of {@code O(n)}. Depending on the type of
|
||||
|
@ -298,16 +308,19 @@ public class CollectionUtils {
|
|||
* @param coll1 the first collection, must not be null
|
||||
* @param coll2 the second collection, must not be null
|
||||
* @return <code>true</code> iff the intersection of the collections has the same cardinality
|
||||
* of the second collection
|
||||
* as the set of unique elements from the second collection
|
||||
* @since 4.0
|
||||
* @see #intersection
|
||||
*/
|
||||
public static boolean containsAll(final Collection<?> coll1, final Collection<?> coll2) {
|
||||
if (coll2.isEmpty()) {
|
||||
return true;
|
||||
} else {
|
||||
Collection<Object> result = CollectionUtils.<Object>intersection(coll1, coll2);
|
||||
return result.size() == coll2.size();
|
||||
final SetOperationCardinalityHelper<Object> helper =
|
||||
new SetOperationCardinalityHelper<Object>(coll1, coll2);
|
||||
for (final Object obj : helper) {
|
||||
helper.setCardinality(obj, helper.min(obj));
|
||||
}
|
||||
return helper.list().size() == helper.sizeB();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,6 +252,10 @@ public class CollectionUtilsTest extends MockTestCase {
|
|||
final Collection<String> odds = new ArrayList<String>(2);
|
||||
odds.add("1");
|
||||
odds.add("3");
|
||||
final Collection<String> multiples = new ArrayList<String>(3);
|
||||
multiples.add("1");
|
||||
multiples.add("3");
|
||||
multiples.add("1");
|
||||
|
||||
assertTrue("containsAll({1},{1,3}) should return false.", !CollectionUtils.containsAll(one, odds));
|
||||
assertTrue("containsAll({1,3},{1}) should return true.", CollectionUtils.containsAll(odds, one));
|
||||
|
@ -267,6 +271,10 @@ public class CollectionUtilsTest extends MockTestCase {
|
|||
assertTrue("containsAll({1,3},{}) should return true.", CollectionUtils.containsAll(odds, empty));
|
||||
assertTrue("containsAll({},{1,3}) should return false.", !CollectionUtils.containsAll(empty, odds));
|
||||
assertTrue("containsAll({},{}) should return true.", CollectionUtils.containsAll(empty, empty));
|
||||
|
||||
assertTrue("containsAll({1,3},{1,3,1}) should return true.", CollectionUtils.containsAll(odds, multiples));
|
||||
assertTrue("containsAll({1,3,1},{1,3,1}) should return true.", CollectionUtils.containsAll(odds, odds));
|
||||
assertTrue("containsAll({1,3,1},{1,3,1}) should return true.", CollectionUtils.containsAll(odds, odds));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue