[COLLECTIONS-446] Added method isEqualCollection(Collection, Collection, Equator) to CollectionUtils.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1453012 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5f2a8837c0
commit
41f5524e92
|
@ -22,6 +22,9 @@
|
|||
<body>
|
||||
|
||||
<release version="4.0" date="TBA" description="Next release">
|
||||
<action issue="COLLECTIONS-446" dev="tn" type="add" due-to="Matt Lachman">
|
||||
Added method "CollectionUtils#isEqualCollection(Collection, Collection, Equator)".
|
||||
</action>
|
||||
<action issue="COLLECTIONS-447" dev="tn" type="fix" due-to="Jeffrey Barnes">
|
||||
Tree traversal with a TreeListIterator will not be affected anymore by
|
||||
the removal of an element directly after a call to previous().
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.commons.collections.collection.SynchronizedCollection;
|
|||
import org.apache.commons.collections.collection.TransformedCollection;
|
||||
import org.apache.commons.collections.collection.UnmodifiableBoundedCollection;
|
||||
import org.apache.commons.collections.collection.UnmodifiableCollection;
|
||||
import org.apache.commons.collections.functors.Equator;
|
||||
import org.apache.commons.collections.functors.TruePredicate;
|
||||
|
||||
/**
|
||||
|
@ -522,6 +523,78 @@ public class CollectionUtils {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> iff the given {@link Collection}s contain
|
||||
* exactly the same elements with exactly the same cardinalities.
|
||||
* <p>
|
||||
* That is, iff the cardinality of <i>e</i> in <i>a</i> is
|
||||
* equal to the cardinality of <i>e</i> in <i>b</i>,
|
||||
* for each element <i>e</i> in <i>a</i> or <i>b</i>.
|
||||
*
|
||||
* @param a the first collection, must not be null
|
||||
* @param b the second collection, must not be null
|
||||
* @param equator the Equator used for testing equality
|
||||
* @return <code>true</code> iff the collections contain the same elements with the same cardinalities.
|
||||
* @throws IllegalArgumentException if the equator is null
|
||||
* @since 4.0
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" }) // we don't know the types due to wildcards in the signature
|
||||
public static boolean isEqualCollection(final Collection<?> a, final Collection<?> b, final Equator<?> equator) {
|
||||
if (equator == null) {
|
||||
throw new IllegalArgumentException("equator may not be null");
|
||||
}
|
||||
|
||||
if(a.size() != b.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Transformer transformer = new Transformer() {
|
||||
public EquatorWrapper<?> transform(Object input) {
|
||||
return new EquatorWrapper(equator, input);
|
||||
}
|
||||
};
|
||||
|
||||
return isEqualCollection(collect(a, transformer), collect(b, transformer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps another object and uses the provided Equator to implement
|
||||
* {@link #equals(Object)} and {@link #hashCode()}.
|
||||
* <p>
|
||||
* This class can be used to store objects into a Map.
|
||||
*
|
||||
* @param <O> the element type
|
||||
* @since 4.0
|
||||
*/
|
||||
private static class EquatorWrapper<O> {
|
||||
private final Equator<O> equator;
|
||||
private final O object;
|
||||
|
||||
public EquatorWrapper(final Equator<O> equator, final O object) {
|
||||
this.equator = equator;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public O getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof EquatorWrapper)) {
|
||||
return false;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
EquatorWrapper<O> otherObj = (EquatorWrapper<O>) obj;
|
||||
return equator.equate(object, otherObj.getObject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return equator.hash(object);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of occurrences of <i>obj</i> in <i>coll</i>.
|
||||
*
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.apache.commons.collections.collection.PredicatedCollection;
|
|||
import org.apache.commons.collections.collection.SynchronizedCollection;
|
||||
import org.apache.commons.collections.collection.TransformedCollection;
|
||||
import org.apache.commons.collections.collection.UnmodifiableCollection;
|
||||
import org.apache.commons.collections.functors.DefaultEquator;
|
||||
import org.apache.commons.collections.functors.Equator;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -515,6 +517,36 @@ public class CollectionUtilsTest extends MockTestCase {
|
|||
assertTrue(CollectionUtils.isEqualCollection(b, a));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsEqualCollectionEquator() {
|
||||
Collection<Integer> collB = CollectionUtils.collect(collectionB, TRANSFORM_TO_INTEGER);
|
||||
|
||||
// odd / even equator
|
||||
final Equator<Integer> e = new Equator<Integer>() {
|
||||
public boolean equate(Integer o1, Integer o2) {
|
||||
if (o1.intValue() % 2 == 0 ^ o2.intValue() % 2 == 0) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
public int hash(Integer o) {
|
||||
return o.intValue() % 2 == 0 ? Integer.valueOf(0).hashCode() : Integer.valueOf(1).hashCode();
|
||||
}
|
||||
};
|
||||
|
||||
assertTrue(CollectionUtils.isEqualCollection(collectionA, collectionA, e));
|
||||
assertTrue(CollectionUtils.isEqualCollection(collectionA, collB, e));
|
||||
assertTrue(CollectionUtils.isEqualCollection(collB, collectionA, e));
|
||||
|
||||
final Equator<Number> defaultEquator = new DefaultEquator<Number>();
|
||||
assertFalse(CollectionUtils.isEqualCollection(collectionA, collectionB, defaultEquator));
|
||||
assertFalse(CollectionUtils.isEqualCollection(collectionA, collB, defaultEquator));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testIsEqualCollectionNullEquator() {
|
||||
CollectionUtils.isEqualCollection(collectionA, collectionA, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsProperSubCollection() {
|
||||
final Collection<String> a = new ArrayList<String>();
|
||||
|
|
Loading…
Reference in New Issue