commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Arun Thomas" <arun.tho...@paybytouch.com>
Subject RE: [collections] [PATCH] CompositeCollection class for Commons-Collections
Date Wed, 05 Nov 2003 21:21:13 GMT
"The toCollection(), toList(), etc. stuff would be no different (other than the collection
overhead) from toArray().  What would get copied are object references."

I understood the proposed methods would work in this way.  I guess my questions is why it
would be particularly useful to add these extra methods (toCollection, toList, toSet) as opposed
to simply passing the composite collection to the addAll() method of the Collection/List/Set?
 

In general, if a particular behaviour is expected of the resulting collection/list/set, the
particular method used will be something to the effect of: toCollection(Collection c), or
toList(List l) where a object with the expected characteristics can be passed in for filling.
 But in this case, all it can do is call addAll on the supplied collection (or iterate and
add each element individually I suppose).  

So, I'm not quite sure why this would be a useful/good thing?  

Also, I think that the behaviour you propose for nested collections is actually quite different
from what composite collection provides.  The composite allows a set of collections to be
treated as a collection (at least, so I understood from previous mails with code), which doesn't
really consider the contents of those individual collections.  

I do think that many of those behaviours could be useful, but I'm not sure that overloading
is the way to go about it.  Since a CompositeCollection IS A Collection, a user of the overloaded
methods may not necessarily know whether the collection at hand is a Collection or a CompositeCollection,
and could find unexpected behaviour when calling the overloaded methods.   

Have I understood your proposals correctly?

Cheers, 
-AMT

-----Original Message-----
From: Phil Steitz [mailto:phil@steitz.com] 
Sent: Wednesday, November 05, 2003 10:42 AM
To: Jakarta Commons Developers List
Subject: Re: [collections] [PATCH] CompositeCollection class for Commons-Collections


Arun Thomas wrote:
 >>> The last comment suggests another possibly useful method:  >>> toList(),
returning an aggregated collection consisting of all of  >>> the objects in the composite
collections.  >>  >  > In this case, will there be a clever way to return an aggregation
of  > this sort that isn't simply a new object with copies of all elements  > of the
contained objects?  If that's the case, then is seems more  > reasonable to leave the creation
of this type of object to the user -  > create a new object passing in the composite collection
in the  > constructor, or use addAll(Collection c).  >  > If there's a clever way
to handle provide the implementation of  > List/Set/Collection using the contained collections
as a base, that  > might be interesting, but otherwise....

That's essentially what the CompositeCollection class does -- decorates 
the aggregated collections with a Collection interface.

The toCollection(), toList(), etc. stuff would be no different (other 
than the collection overhead) from toArray().  What would get copied are 
object references.

Thinking a little more, I suppose that the semantics of both toArray() 
and toCollection() could be extended to fully flatten what could 
effectively become a tree of collections.  Since CompositeCollection is 
a Collection, composites could themselves be aggregated (as in Brian's 
use case above).  In this case, extensions of toArray() or 
toCollection() returning all of the objects nested in the collections 
might make sense. Of course this applies to ordinary collections as 
well.  Could be that if these methods are useful, they all (including 
CompositeCollection.toCollection()) belong in CollectionUtils, so 
instead of CompositeCollection.toCollection(), we just overload 
CollectionUtils.union(CompositeCollection) (maybe also intersection) 
and, if the "tree traversal" stuff is useful, we add something like 
CollectionUtils.traverse(Collection) that unwinds nested collections, 
returning a flattened list of objects that are not collections 
(carefully avoiding getting stuck in cycles) and maybe also 
CollectionUtils.rank(Collection) that returns the integer length of the 
longest branch in the tree. Individual objects also have ranks -- 
CollectionUtils.rank(Collection, Object) = level where Object is first 
encountered in breadth-first search.  OK, I will shut up now, starting 
to sound too much like a logician...Is any of this useful?

Phil
 >
 > Cheers, -AMT
 >
 > -----Original Message----- From: Phil Steitz [mailto:phil@steitz.com]  >  Sent: Wednesday,
November 05, 2003 8:31 AM To: Jakarta Commons  > Developers List Subject: Re: [collections]
[PATCH]  > CompositeCollection class for Commons-Collections  >  >  > Brian McCallister
wrote:  >  >> On Wednesday, November 5, 2003, at 12:10 AM, Phil Steitz wrote:  >>
 >>  >>> I think that that javadoc for remove is incorrect when it says:  >>>
"This implementation calls <code>remove()</code> on each  >>> collection."
It stops when it finds the element to be removed.  >>> The contract needs to be made
more explicit here.  It might  >>> actually be better to push remove() into the Mutator,
since one  >>> could argue that the current "remove strategy" (kill the first  >>>
one found) is no less arbitrary than a default "add" strategy  >>> that just adds
to the last collection.  Might be better to make  >>> this pluggable like add.  >>
 >>  >> To quote the Collection API doc: <quote> Removes a single instance
 >> of the specified element from this collection, if it is present  >> (optional
operation).  More formally, removes an element e such  >> that (o==null ?  e==null :
 o.equals(e)), if this collection  >> contains one or more such  elements. </quote>
 >>  >> I agree that this could be pluggable, but I think that providing a  >>
"remove first found" as a default is very reasonable in this case  >> as it fits the
idiomatic behavior people expect from extent  >> collections.  >  >  > Note
the similarity to the API doc for add: "Ensures that this  > collection contains the specified
element (optional operation).  > Returns true if this collection changed as a result of
the call.  > (Returns false if this collection does not permit duplicates and  > already
contains the specified element.)"  >  > My point is that "kill first" in a composite
collection is no more  > "natural" than "add last".  I would be OK with both being defaulted
 > but modifiable via Mutator.  Since "the collection" could mean either  > the aggregate
or *each* of the summands in each case, I see both add  > and remove as ambiguous (hence
the need for strategies).  This is a  > small point.  >  >  >> +0 (non-binding)
for putting this into the CollectionMutator but  >> providing present behavior as default
if no mutator set (rather  >> than an exception as add/addAll do. This is internally
inconsistent  >> though so I would welcome better ideas.  >>  >>  >>>
The containsAll javadoc says "This is O(n^2) at the moment, be  >>> careful using
it.".  >>  >>  >> It is not correct anymore. It was in the original version
but the  >> implementation has changed significantly already =)  >>  >>
 >>> I am curious about how much faster this can be done without an  >>>
ordering.  >>  >>  >> Dropping ordering on what?  >  >  > What
I meant was that without assuming an ordering on the aggregate  > (so binary search would
be possible), is there a faster way to do the  > "*all" methods. I assume that if there
is a clever way to do this,  > that is what the JDK methods do.  >  >  >>>
The last comment suggests another possibly useful method:  >>> toList(), returning
an aggregated collection consisting of all of  >>> the objects in the composite collections.
 >>  >>  >> That works for me, though I would make it a Collection and return
 >> the actual type of whichever subclass. I suspect Stephen will  >> suggest
that it be toCollection(), toList(), and toSet()  >> respectively in order to allow
greater specificity of the return  >> type, which I am also okay with.  >  > 
> What do you mean by "whichever subclass"?  The aggregated collections  >  could be
of multiple different types. That makes an interesting  > problem. I suppose that toCollection()
could return an instance of  > the one common type if the summands are "homogeneous" (all
the same  > type), otherwise default to a (Array?)List or (Hash?)Set.  I agree  > that
toSet() would also be natural. Need to think about these things  > some more.  It might
be better to just have the API take the  > aggregation target as an actual parameter --
i.e.  > toCollection(collection), effectively punting the issue of return  > types.
 >  > Anyone have any objections to committing this to the decorators  > subpackage?
 >  > Phil  >  >  >> Hmm, would be nice if Java let you override a method
to return a  >> subclass of the return type of the method being overridden. It  >>
would satisfy the static typing still.  >>  >> -Brian  >>  >> PS:
I have attached changes discussed  >>  >>  >  >  >  >  > ---------------------------------------------------------------------
 >  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