Hmm..my understanding of "Bag" would have matched Mike Zatko's, ie it is
a collection where multiple instances of identical objects can be added,
and those *instances* are added to the collection.

I have therefore attached a patch that updates the javadoc for class
o.a.c.c.Bag to make this clear. I hope these changes are acceptable.

Note that the javadoc changes I have made indicate that when duplicate
objects are added, a reference to the *first* added object is retained.
If this is not the case, then this would need to be updated.

Thanks,

Simon

On Tue, 2005-03-15 at 22:51 +0000, Stephen Colebourne wrote:
> You describe the correct behaviour of SortedBag, and collections in general. 
> Most collections use .equals() comparisons.
> 
> You have two choices:
> a) Write a sorted collection that uses == for comparison instead of .equals
> 
> b) Use a TreeSet, but wrap each of your objects in an inner class style 
> wrapper, eg:
> public class Wrapper {
>   public Object realData;
> }
> 
> Stephen
> 
> ----- Original Message ----- 
> From: "Mike Zatko" <[EMAIL PROTECTED]>
> > FYI, I did try a sorted bag which appeared to be what I was looking for. 
> > But, for some reason if you add 2 identical objects (deep copied) and add 
> > them to the bag, it will merely overwrites the first objects reference 
> > with the second objects reference. To me, this seems like it would be a 
> > bug, but I could be wrong. Any thoughts?
> >
> >
> > Mike Zatko wrote:
> >
> >> I need a sorted collection that also allows deep copied duplicate objects 
> >> (exact same object, different memory addresses). Is there a collection 
> >> that fits that requirement? I've been having difficulty finding one 
> >> myself. Thanks for any help.
> >>
Index: Bag.java
===================================================================
--- Bag.java	(revision 157629)
+++ Bag.java	(working copy)
@@ -27,6 +27,11 @@
  * Calling [EMAIL PROTECTED] #getCount(Object)} on <code>a</code> would return 2, while
  * calling [EMAIL PROTECTED] #uniqueSet()} would return <code>{a, b, c}</code>.
  * <p>
+ * When comparing items in the bag for any reason, the .equals method of the
+ * items is used rather than identity comparison. The [EMAIL PROTECTED] #add},
+ * [EMAIL PROTECTED] #getCount}, [EMAIL PROTECTED] #remove} and [EMAIL PROTECTED] #iterator} methods are
+ * particularly affected; see the javadoc for those methods for more information.
+ * <p>
  * <i>NOTE: This interface violates the [EMAIL PROTECTED] Collection} contract.</i> 
  * The behavior specified in many of these methods is <i>not</i> the same
  * as the behavior specified by <code>Collection</code>.
@@ -49,6 +54,11 @@
      * Returns the number of occurrences (cardinality) of the given
      * object currently in the bag. If the object does not exist in the
      * bag, return 0.
+     * <p>
+     * Comparisons are done with the <i>equals</i> method, not instance
+     * comparison. The returned value therefore indicates how many objects
+     * have previously been added to this bag which are <i>equal</i> to the
+     * specified object.
      * 
      * @param object  the object to search for
      * @return the number of occurrences of the object, zero if not found
@@ -67,6 +77,14 @@
      * according to the [EMAIL PROTECTED] Collection#add(Object)} contract, it 
      * should always return <code>true</code>.  Since it sometimes returns
      * <code>false</code>, this method violates the contract.
+     * <p>
+     * If there is already an object in the bag which is <i>equal</i> to the
+     * specified object, then the occurrence count for the existing object is
+     * incremented rather than adding the specified object to the bag. However
+     * if there is no equal object already in the Bag, then a reference to the
+     * specified object is retained by the collection.
+     * <p>
+     * Objects added to this bag should not be modified.
      *
      * @param object  the object to add
      * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
@@ -79,6 +97,10 @@
      * If the object is already in the [EMAIL PROTECTED] #uniqueSet()} then increment its
      * count as reported by [EMAIL PROTECTED] #getCount(Object)}. Otherwise add it to the
      * [EMAIL PROTECTED] #uniqueSet()} and report its count as <code>nCopies</code>.
+     * <p>
+     * If there is already an object in the bag which is <i>equal</i> to the
+     * specified object, then the occurrence count for the existing object is
+     * incremented by nCopies.
      * 
      * @param object  the object to add
      * @param nCopies  the number of copies to add
@@ -88,12 +110,12 @@
 
     /**
      * <i>(Violation)</i>
-     * Removes all occurrences of the given object from the bag.
+     * Removes from the bag all occurrences equal to the given object.
      * <p>
-     * This will also remove the object from the [EMAIL PROTECTED] #uniqueSet()}.
+     * This will also remove the removed object from the [EMAIL PROTECTED] #uniqueSet()}.
      * <p>
      * According to the [EMAIL PROTECTED] Collection#remove(Object)} method,
-     * this method should only remove the <i>first</i> occurrence of the
+     * this method should only remove one (the <i>first</i>) occurrence of the
      * given object, not <i>all</i> occurrences.
      *
      * @return <code>true</code> if this call changed the collection
@@ -101,7 +123,8 @@
     boolean remove(Object object);
 
     /**
-     * Removes <code>nCopies</code> copies of the specified object from the Bag.
+     * Removes from the bag <code>nCopies</code> copies of an object equal to
+     * the specified object.
      * <p>
      * If the number of copies to remove is greater than the actual number of
      * copies in the Bag, no error is thrown.
@@ -140,6 +163,11 @@
      * that cardinality should <i>not</i> be respected; this method should
      * return true if the bag contains at least one of every object contained
      * in the given collection.
+     * <p>
+     * Comparisons are done by value (with the <i>equals</i> method), not by
+     * instance comparisons. This method therefore returns true if parameter
+     * coll contains an object X and this bag contains a different object
+     * <i>which is equal</i> to X.
      * 
      * @param coll  the collection to check against
      * @return <code>true</code> if the Bag contains all the collection
@@ -153,11 +181,15 @@
      * <code>coll</code> contains <code>n</code> copies of a given object,
      * the bag will have <code>n</code> fewer copies, assuming the bag
      * had at least <code>n</code> copies to begin with.
-     *
-     * <P>The [EMAIL PROTECTED] Collection#removeAll(Collection)} method specifies
+     * <p>
+     * The [EMAIL PROTECTED] Collection#removeAll(Collection)} method specifies
      * that cardinality should <i>not</i> be respected; this method should
      * remove <i>all</i> occurrences of every object contained in the 
      * given collection.
+     * <p>
+     * Comparisons are done by value (with the <i>equals</i> method), not by
+     * instance comparisons. This method will therefore remove from this bag
+     * values <i>which are equal</i> to the objects in collection <i>coll</i>.
      *
      * @param coll  the collection to remove
      * @return <code>true</code> if this call changed the collection
@@ -174,8 +206,8 @@
      * <code>e</code> is an object in the bag but
      * <code>!coll.contains(e)</code>, then remove <code>e</code> and any
      * of its copies.
-     *
-     * <P>The [EMAIL PROTECTED] Collection#retainAll(Collection)} method specifies
+     * <p>
+     * The [EMAIL PROTECTED] Collection#retainAll(Collection)} method specifies
      * that cardinality should <i>not</i> be respected; this method should
      * keep <i>all</i> occurrences of every object contained in the 
      * given collection.
@@ -189,6 +221,12 @@
      * Returns an [EMAIL PROTECTED] Iterator} over the entire set of members,
      * including copies due to cardinality. This iterator is fail-fast
      * and will not tolerate concurrent modifications.
+     * <p>
+     * Because the [EMAIL PROTECTED] #add} method retains a reference to only a single
+     * instance when duplicate objects (ones that are <i>equal</i>) are added
+     * to a bag, the objects returned by this iterator will be <i>equal</i>
+     * to the values passed to the add method, but may not be <i>the same</i>
+     * objects.
      * 
      * @return iterator over all elements in the Bag
      */

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to