Arun Thomas wrote: > "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?
Now I understand and agree (though it will be interesting to test this). > > 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. >
Yes. I agree. Overloading would not be a good idea, for the reason that you gave.
> Have I understood your proposals correctly? > > Cheers, -AMT > > -----Original Message----- From: Phil Steitz [mailto:[EMAIL PROTECTED] > 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:[EMAIL PROTECTED] > 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: [EMAIL PROTECTED] >> For additional commands, e-mail: >> [EMAIL PROTECTED] >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [EMAIL PROTECTED] >> For additional commands, e-mail: >> [EMAIL PROTECTED] >> > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] >
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]