Generic tree implementation in Java

Viewed 75240

Is anyone aware of a generic tree (nodes may have multiple children) implementation for Java? It should come from a well trusted source and must be fully tested.

It just doesn't seem right implementing it myself. Almost reminds me of my university years when we were supposed to write all our collections ourselves.

EDIT: Found this project on java.net, might be worth looking into.

10 Answers

Ah, I was going to post a shameless plug to my solution and saw that someone already posted a link to it. Yeah, I had the same issue and I basically ended up writing my own Generic Tree. I've got tests for the tree node and the tree itself.

I implemented the node as an object having a data field and a list of nodes (which are the children of that node).

http://vivin.net/2010/01/30/generic-n-ary-tree-in-java/

I found an absolutely fantastic library http://jung.sourceforge.net, see the javadoc http://jung.sourceforge.net/doc/api/index.html . It is much more than just a graph implementation. With it you can visualize and layout graphs; plus, it has a bunch of standard graph algorithms you can use out of the box. Go, check it out! Although I ended up implementing my own basic graph (I didn't know of JUNG before), I use this library for visualization. It looks very neat!

When in need of a tree I typically use following interface, and implement it accordingly.

  /**
   * Generic node interface
   * 
   * @param <T> type of contained data
   * @param <N> self-referential type boundary that captures the implementing type
   */
  interface Node<T, N extends Node<T, N>>
  {

    public T getObject();

    public boolean addChild(N node);

    public List<N> getChildren();

  }

An implementation could be

  class StringNode implements Node<String, StringNode>
  {

    private final String value;

    public StringNode(String value)
    {
      this.value = value;
    }

    @Override
    public String getObject()
    {
      return value;
    }

    @Override
    public boolean addChild(StringNode node)
    {
      // add child
      return false;
    }

    @Override
    public List<StringNode> getChildren()
    {
      // return children
      return Collections.emptyList();
    }

  }

The advantage here is the flexibility gained by implementing algorithms against the interface. A rather simple example could be

  public <T, N extends Node<T, ? extends N>> N performAlgorithm(N node)
  {
    if (!node.getChildren().isEmpty())
      return node.getChildren().get(0);

    return node;
  }

The method can be used with the inteface type or concrete implementations

StringNode sn = new StringNode("0");
Node<String, StringNode> node = sn;

// perform computations on the interface type
Node<String, StringNode> result = performAlgorithm(node);

// or use a concrete implementation
StringNode result2 = performAlgorithm(sn);

If you need an enterprise-level node tree, you could look into Java Content Repository (JCR). But it is far from the simple in-memory node tree solutions suggested here and more of a multi-user XML database with SQL and XPath.

Related