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]