commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stephen Colebourne" <scolebou...@btopenworld.com>
Subject Re: [collections] [patch] List & Set equals() and hashCode() implementations
Date Tue, 08 Apr 2003 23:43:25 GMT
Yes, consistency will be important. I'll have to take another look...
Stephen

----- Original Message -----
From: "Neil O'Toole" <neilotoole@users.sourceforge.net>
To: "Jakarta Commons Developers List" <commons-dev@jakarta.apache.org>
Sent: Tuesday, April 08, 2003 1:05 AM
Subject: Re: [collections] [patch] List & Set equals() and hashCode()
implementations


> Stephen,
>
> Actually, while I'm touching on the issue of method names... First,
> though I have no philosophical ;) objection to renaming
> SetUtils#isEqualSet() and ListUtils#isEqualList() to "equals()", I do
> note that CollectionUtils features a method "isEqualCollection()" - and
> this is why I chose the above method names. Again, I have no stance on
> which names to use, but I would prefer to see consistency across the
> package. Thoughts?
>
> - Neil
>
>
>
> --- Stephen Colebourne <scolebourne@btopenworld.com> wrote:
> > Patches applied with name/format changes, thanks.
> > Stephen
> >
> > ----- Original Message -----
> > From: "Neil O'Toole" <neilotoole@yahoo.com>
> > To: "Jakarta Commons Developers List"
> > <commons-dev@jakarta.apache.org>;
> > <neilotoole@users.sourceforge.net>
> > Sent: Sunday, March 23, 2003 6:23 AM
> > Subject: [collections] [patch] List & Set equals() and hashCode()
> > implementations
> >
> >
> > >
> > > These patches provides implementations of equals() and hashCode()
> > for
> > > Set and List, as per their contracts. These are useful if you are
> > > writing a Set or List implementation that is not a subclass of
> > > AbstractSet or AbstractList (which provides these implementations).
> > The
> > > operations are equivalent to the AbstractSet/List implementations
> > > (obviously...). Test cases also provided.
> > >
> > > - Neil O'Toole
> >
> >
> >
> --------------------------------------------------------------------------
--
> > ----
> >
> >
> > > Index: ListUtils.java
> > > ===================================================================
> > > RCS file:
> >
>
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/coll
> > ections/ListUtils.java,v
> > > retrieving revision 1.13
> > > diff -u -r1.13 ListUtils.java
> > > --- ListUtils.java 10 Jan 2003 20:21:23 -0000 1.13
> > > +++ ListUtils.java 23 Mar 2003 04:41:19 -0000
> > > @@ -553,4 +553,78 @@
> > >          return new FixedSizeList(list);
> > >      }
> > >
> > > + /**
> > > + * Tests two lists for value-equality as per the equality contract
> > in
> > {@link java.util.List}.
> > > + * The relevant text (slightly paraphrased as this is a static
> > method)
> > is:
> > > + *
> > > + * <blockquote>
> > > + * Compares the two list objects for equality.  Returns
> > > + * <tt>true</tt> if and only if both
> > > + * lists have the same size, and all corresponding pairs of
> > elements in
> > > + * the two lists are <i>equal</i>.  (Two elements <tt>e1</tt>
and
> > > + * <tt>e2</tt> are <i>equal</i> if <tt>(e1==null
? e2==null :
> > > + * e1.equals(e2))</tt>.)  In other words, two lists are defined to
> > be
> > > + * equal if they contain the same elements in the same order.
> > This
> > > + * definition ensures that the equals method works properly across
> > > + * different implementations of the <tt>List</tt> interface.
> > > + * </blockquote>
> > > +
> > > + * <b>Note:</b> The behaviour of this method is undefined if the
> > lists
> > are
> > > + * modified during the equals comparison.
> > > + * @param a
> > > + * @param b
> > > + * @return boolean whether the lists are equal by value comparison
> > > + * @see java.util.List
> > > + */
> > > + public final static boolean isEqualList( final List a, final List
> > b) {
> > > +
> > > + if ( a == b )
> > > + {
> > > + return true;
> > > + }
> > > +
> > > + if ( a.size() != b.size() )
> > > + {
> > > + return false;
> > > + }
> > > +
> > > + ListIterator ia = a.listIterator();
> > > + ListIterator ib = b.listIterator();
> > > +
> > > + Object o1 = null;
> > > + Object o2 = null;
> > > +
> > > + while (ia.hasNext() && ib.hasNext())
> > > + {
> > > + o1 = ia.next();
> > > + o2 = ib.next();
> > > +
> > > + if (!(o1 == null ? o2 == null : o1.equals(o2)))
> > > + {
> > > + return false;
> > > + }
> > > + }
> > > +
> > > + return !(ia.hasNext() || ib.hasNext());
> > > + }
> > > +
> > > + /**
> > > + * Generates a hashcode using the algorithm specified in {@link
> > java.util.List#hashCode()}.
> > > + *
> > > + * @see java.util.List#hashCode()
> > > + * @return int the hash code
> > > + */
> > > + public static final int calcHashCodeUsingListAlgorithm(Collection
> > c) {
> > > +
> > > + int hashCode = 1;
> > > + Iterator iter = c.iterator();
> > > + Object object = null;
> > > +
> > > + while (iter.hasNext())
> > > + {
> > > + object = iter.next();
> > > + hashCode = 31 * hashCode + (object == null ? 0 :
> > object.hashCode());
> > > + }
> > > + return hashCode;
> > > + }
> > >  }
> > >
> >
> >
> >
> --------------------------------------------------------------------------
--
> > ----
> >
> >
> > > Index: SetUtils.java
> > > ===================================================================
> > > RCS file:
> >
>
/home/cvspublic/jakarta-commons/collections/src/java/org/apache/commons/coll
> > ections/SetUtils.java,v
> > > retrieving revision 1.9
> > > diff -u -r1.9 SetUtils.java
> > > --- SetUtils.java 10 Jan 2003 20:21:23 -0000 1.9
> > > +++ SetUtils.java 23 Mar 2003 04:42:53 -0000
> > > @@ -57,8 +57,10 @@
> > >   */
> > >  package org.apache.commons.collections;
> > >
> > > +import java.util.Collection;
> > >  import java.util.Collections;
> > >  import java.util.Comparator;
> > > +import java.util.Iterator;
> > >  import java.util.Set;
> > >  import java.util.SortedSet;
> > >  import java.util.TreeSet;
> > > @@ -255,4 +257,63 @@
> > >          return new PredicatedSortedSet(set, predicate);
> > >      }
> > >
> > > + /**
> > > + * Tests two sets for equality as per the <code>equals()</code>
> > contract
> > in {@link java.util.Set}.
> > > + * The relevant text (slightly paraphrased as this is a static
> > method)
> > is:
> > > + *
> > > + * <blockquote>
> > > + * <p>Two sets are considered equal if they have
> > > + * the same size, and every member of the first set is contained
> > in
> > > + * the second. This ensures that the <tt>equals</tt> method works
> > > + * properly across different implementations of the <tt>Set</tt>
> > > + * interface.</p>
> > > + *
> > > + * <p>
> > > + * This implementation first checks if the two sets are the same
> > object:
> > > + * if so it returns <tt>true</tt>.  Then, it checks if the two
> > sets are
> > > + * identical in size; if not, it returns false. If so, it returns
> > > + * <tt>a.containsAll((Collection) b)</tt>.</p>
> > > + * </blockquote>
> > > + *
> > > + * @return boolean whether the sets are equal as per the contract
> > in
> > {@link java.util.Set}.
> > > + * @see java.util.Set#equals(Object)
> > > + */
> > > + public final static boolean isEqualSet( final Set a, final Set b)
> > > + {
> > > + if ( a == b )
> > > + {
> > > + return true;
> > > + }
> > > +
> > > + if ( a.size() != b.size() )
> > > + {
> > > + return false;
> > > + }
> > > +
> > > + return a.containsAll(b);
> > > +
> > > + }
> > > +
> > > + /**
> > > + * Generates a hashcode using the algorithm specified in {@link
> > java.util.Set#hashCode()}.
> > > + *
> > > + * @see java.util.Set#hashCode()
> > > + * @return int the hash code
> > > + */
> > > + public static final int calcHashCodeUsingSetAlgorithm(Collection
> > c)
> > > + {
> > > + int hashCode = 0;
> > > + Iterator iter = c.iterator();
> > > + Object object = null;
> > > +
> > > + while (iter.hasNext())
> > > + {
> > > + object = iter.next();
> > > + if (object != null)
> > > + {
> > > + hashCode += object.hashCode();
> > > + }
> > > + }
> > > + return hashCode;
> > > + }
> > >  }
> > >
> >
> >
> >
> --------------------------------------------------------------------------
--
> > ----
> >
> >
> > > Index: TestListUtils.java
> > > ===================================================================
> > > RCS file:
> >
>
/home/cvspublic/jakarta-commons/collections/src/test/org/apache/commons/coll
> > ections/TestListUtils.java,v
> > > retrieving revision 1.5
> > > diff -u -r1.5 TestListUtils.java
> > > --- TestListUtils.java 12 Oct 2002 22:36:22 -0000 1.5
> > > +++ TestListUtils.java 23 Mar 2003 04:43:31 -0000
> > > @@ -61,6 +61,7 @@
> > >  package org.apache.commons.collections;
> > >
> > >  import java.util.ArrayList;
> > > +import java.util.Arrays;
> > >  import java.util.Collection;
> > >  import java.util.List;
> > >
> > > @@ -126,7 +127,43 @@
> > >          assertEquals(6, list.size());
> > >      }
> > >
> > > -
> > > + public void testIsEqualList() {
> > > +
> > > + Collection data = Arrays.asList( new String[] { "a", "b", "c" });
> > > +
> > > +
> > > + List a = new ArrayList( data );
> > > + List b = new ArrayList( data );
> > > +
> > > + // we know this will work
> > > + assertTrue( a.equals( b ));
> > > +
> > > + // this should also work
> > > + assertTrue( ListUtils.isEqualList( a, b ));
> > > +
> > > + a.clear();
> > > + // this should fail
> > > + assertFalse( ListUtils.isEqualList( a, b ));
> > > + }
> > > +
> > > + public void testCalcHashCodeUsingSetAlgorithm() {
> > > +
> > > + Collection data = Arrays.asList( new String[] { "a", "b", "c" });
> > > +
> > > + List a = new ArrayList( data );
> > > + List b = new ArrayList( data );
> > > +
> > > + // we know this will work
> > > + assertTrue( a.hashCode() == b.hashCode() );
> > > +
> > > + assertTrue( ListUtils.calcHashCodeUsingListAlgorithm( a ) ==
> > ListUtils.calcHashCodeUsingListAlgorithm( b ));
> > > +
> > > + a.clear();
> > > + // this shouldn't work
> > > + assertFalse( ListUtils.calcHashCodeUsingListAlgorithm( a ) ==
> > ListUtils.calcHashCodeUsingListAlgorithm( b ));
> > > +
> > > + }
> > > +
> > >  }
> > >
> > >
> > >
> >
> >
> >
> --------------------------------------------------------------------------
--
> > ----
> >
> >
> > > Index: TestSetUtils.java
> > > ===================================================================
> > > RCS file:
> >
>
/home/cvspublic/jakarta-commons/collections/src/test/org/apache/commons/coll
> > ections/TestSetUtils.java,v
> > > retrieving revision 1.3
> > > diff -u -r1.3 TestSetUtils.java
> > > --- TestSetUtils.java 19 Feb 2003 20:33:11 -0000 1.3
> > > +++ TestSetUtils.java 23 Mar 2003 04:43:46 -0000
> > > @@ -60,6 +60,7 @@
> > >   */
> > >  package org.apache.commons.collections;
> > >
> > > +import java.util.Arrays;
> > >  import java.util.Collection;
> > >  import java.util.HashSet;
> > >  import java.util.Set;
> > > @@ -110,6 +111,43 @@
> > >          };
> > >      }
> > >
> > > + public void testIsEqualSet() {
> > > +
> > > + Collection data = Arrays.asList( new String[] { "a", "b", "c" });
> > > +
> > > + Set a = new HashSet( data );
> > > + Set b = new HashSet( data );
> > > +
> > > + // we know this will work
> > > + assertTrue( a.equals( b ));
> > > +
> > > + // this should also work
> > > + assertTrue( SetUtils.isEqualSet( a, b ));
> > > +
> > > + a.clear();
> > > + // this shouldn't work
> > > + assertFalse( SetUtils.isEqualSet( a, b ));
> > > + }
> > > +
> > > +
> > > +
> > > + public void testCalcHashCodeUsingSetAlgorithm() {
> > > +
> > > + Collection data = Arrays.asList( new String[] { "a", "b", "c" });
> > > +
> > > + Set a = new HashSet( data );
> > > + Set b = new HashSet( data );
> > > +
> > > + // we know this will work
> > > + assertTrue( a.hashCode() == b.hashCode() );
> > > +
> > > + assertTrue( SetUtils.calcHashCodeUsingSetAlgorithm( a ) ==
> > SetUtils.calcHashCodeUsingSetAlgorithm( b ));
> > > +
> > > + a.clear();
> > > + // this shouldn't work
> > > + assertFalse( SetUtils.calcHashCodeUsingSetAlgorithm( a ) ==
> > SetUtils.calcHashCodeUsingSetAlgorithm( b ));
> > > +
> > > + }
> > >
> > >  }
> > >
> > >
> > >
> >
> >
> >
> --------------------------------------------------------------------------
--
> > ----
> >
> >
> > >
> > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > > For additional commands, e-mail:
> > commons-dev-help@jakarta.apache.org
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message