You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tn...@apache.org on 2013/03/05 22:29:51 UTC

svn commit: r1453012 - in /commons/proper/collections/trunk/src: changes/changes.xml main/java/org/apache/commons/collections/CollectionUtils.java test/java/org/apache/commons/collections/CollectionUtilsTest.java

Author: tn
Date: Tue Mar  5 21:29:50 2013
New Revision: 1453012

URL: http://svn.apache.org/r1453012
Log:
[COLLECTIONS-446] Added method isEqualCollection(Collection, Collection, Equator) to CollectionUtils.

Modified:
    commons/proper/collections/trunk/src/changes/changes.xml
    commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/CollectionUtils.java
    commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/CollectionUtilsTest.java

Modified: commons/proper/collections/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/changes/changes.xml?rev=1453012&r1=1453011&r2=1453012&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/changes/changes.xml (original)
+++ commons/proper/collections/trunk/src/changes/changes.xml Tue Mar  5 21:29:50 2013
@@ -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().

Modified: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/CollectionUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/CollectionUtils.java?rev=1453012&r1=1453011&r2=1453012&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/CollectionUtils.java (original)
+++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/CollectionUtils.java Tue Mar  5 21:29:50 2013
@@ -34,6 +34,7 @@ import org.apache.commons.collections.co
 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;
 
 /**
@@ -523,6 +524,78 @@ public class CollectionUtils {
     }
 
     /**
+     * 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>.
      *
      * @param obj the object to find the cardinality of

Modified: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/CollectionUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/CollectionUtilsTest.java?rev=1453012&r1=1453011&r2=1453012&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/CollectionUtilsTest.java (original)
+++ commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/CollectionUtilsTest.java Tue Mar  5 21:29:50 2013
@@ -32,6 +32,8 @@ import org.apache.commons.collections.co
 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;
 
@@ -516,6 +518,36 @@ public class CollectionUtilsTest extends
     }
 
     @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>();
         final Collection<String> b = new ArrayList<String>();