commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stephen Colebourne" <scolebou...@eurobell.co.uk>
Subject Re: [Collections] TreeNode, TreeIterator, IdentityHashSet proposed collections
Date Mon, 01 Apr 2002 23:49:32 GMT
> It looks like ArrayTreeNode expects users to access
> and manipulate the children of a node by returning a
> List from getChildren(), which users then use to add,
> delete, and access the child nodes. I don't think this
> follows best practices as seen in the java.util
> collections and other commons collections.

Bear in mind the design was a combination of the swing TreeNode and
MutableTreeNode classes. Merge those two and add collections and you get my
TreeNode.

> I would suggest it would be better to keep the list
> holding the children better hidden from the user.
> Children can be added and removed with methods such as
> TreeNode.addChild() and TreeNode.removeChild(). This
> gives different implementations more flexibility in
> how they store children.

True, provided you only go down one level. By hiding the created child node,
you cannot add any children to it, which is a bit of a problem.

> Where your inner class TreeArrayList now has to check
> that the object passed in implements the appropriate
> interface, instead TreeNode.addChild() could simply
> take that interface as a parameter type and not take
> Object, simplifying the code. TreeArrayList can be
> dispensed with entirely, the methods implemented from
> TreeNode would be able to enforce needed requirements,
> such as setting the parent node.
>
> A List or Collection of children can be returned from
> TreeNode, but should be a defensive copy of the
> internal list.

I disagree. A dead copy means less to implement, but means we end up adding
all the List methods to TreeNode. I would suggest that by using a live list
of children we enable applications to use the full interface of List to
manipulate that list of children, such as subList() and retainAll() that
wouldn't be available otherwise. Having an addChild(TreeNode) method on
TreeNode may well be a good idea for ease of use however.

> It would be useful to add a method
> which returns an Iterator for the children of the
> node.

Don't we get this by having the children as a list? No need to duplicate.

> Also, the current implementation requires manual
> creation of TreeNodes by user code. I would suggest
> having methods which take an Object value parameter,
> and handle TreeNode construction internally. In fact,
> I would make these the default methods, with
> Node-handling methods separately named. e.g.:

This could work, but only if the addChild(Object value) method returned the
TreeNode it had created (otherwise you can't add children to it). But
addChild return TreeNode seems a little odd - maybe the name addChildValue
makes more sense? And my view would be that once you expose TreeNode as a
public interface, the default methods should refer to TreeNode.

> A final suggestion, the base interface TreeNode could
> assume that Collections rather than Lists are used
> internally to store children, to allow a lighter
> implementation for applications which don't care about
> ordering. This would just mean removing the
> getChild(int index) method.

Maybe. The trouble is that we would lose the nice extra methods on List for
manipulations. A ListTreeNode subclass could be written, but there would
then be no guarantees that the children added were ListTreeNodes, and the
getParent method would return TreeNode not ListTreeNode. For my current use
of trees, I only use iterators to access the tree, so a collection would be
fine. In the future, I expect index access to be significant which could be
a hassle.

Related to this is the question of hashCode and equals methods. (The other
type of collection is a Set, which needs a hashCode). So far, my view is to
use the == check for equals and the identity hashCode (ie. don't implement
either method). The alternatives are to return equals/hashcode based on the
value, or to traverse the tree to build a composite equals/hashcode. The
former strikes me as too weak - two nodes are not equal just because their
values are equal, because that ignores the children. The latter could
involve some very lengthy calculations, and doesn't strike me as practical.
This would appear to rule out a Set implementation as an alternative to
List. Given that, it seems to me that an ordered list of children isn't a
big overhead, yet gives many benefits.

> A question, in ArrayTreeNode.toString() you use a
> method called Reflection.getShortenedClassName(),
> which I don't have anywhere in my system (using JDK
> 1.3). Where does this come from?

Another of my utilities is a set of reflection utilities. In this case the
code got the class name minus the package name (which ironically doesn't use
reflection!). Its available on joda.org if you want it, but we should really
have a better toString() implementation anyway - more collections like -
including a list of the children.

I need to grab some sleep now, so I won't go into your API just now.

Stephen




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


Mime
View raw message