Java Data Structures – Custom Node/Chain Implementation

collectionsdata structuresdesignjava

I am designing a simple GUI that will allow a user to create a GPX route by clicking repeatedly on a map panel. I am faced with a design dilemma for how to represent the nodes and route. This construct can be abstracted as follows:

  • the user clicks n times on the screen in sequence to create a chain of n nodes
  • after a chain has been completed, a user can add more nodes to it, either by selecting nodes in the middle (inserting between existing nodes) or by simply automatically appending to the end with his next click

At first I was determined to use a Java Collections class to represent the chain, but there are unexpected difficulties with that. On the surface, this would appear to be a perfect example of a LinkedList, but consider as follows. If the user wishes to insert a node in the middle of the chain, he first chooses some node on screen that he wishes to insert a new node before. If the node belongs to a linked list, it will need to maintain a reference to its encompassing list (a somewhat unusual practice, I'd think), and even then we will still have to locate the node in the list before we can insert. So we have to:

  • find the node (linear time)
  • insert the new node (constant time)

Or if I try the same thing with an ArrayList, it also performs at best in linear time.

  • find the node (linear time)
  • insert the new node (linear time)

But neither case really seems desirable. I briefly flirted with the idea of using a LinkedHashSet, but it does not allow insertion into the middle of the linked list, nor does it seem fundamentally correct to use a set implementation for something like this.

So here is what I came up with:

class Node {
    Node previous;
    Node next;
    Chain chain;
}

A Node maintains only a reference to its previous and next nodes, as well as the chain it belongs to (again, this latter part seems unconventional and possibly even wasteful to me, but I'm convinced it may be necessary here).

class Chain {
    Node first;
    Node last;
}

The chain knows only what its first and last nodes are.

Now, if a user wants to insert a node in the middle of the chain? He selects the node, which simply updates the first/last references of itself and its neighbors. If he wants to add nodes to the end of a chain? He simply selects any node on screen (which is aware of what chain it belongs to, and therefore what the last node in that chain is), and the chain immediately begins updating link references for the last node and each node added after it, as well as keeping its own "last" reference up to date.

I really wanted to use a Collections class, but this approach seems better to me. But I'd love to here thoughts/criticisms from more experienced programmers. Thanks.

Best Answer

Mutable circular references are nasty. Just use an ArrayList and don't worry about it.

You can see all of the elements on screen: it's not going to be so long that linear time takes any time.

re dude demanding an explanation why mutable circular references are nasty: like, as in bad code. It's an inefficient use of programmer-thinky-time, not unavoidably problematic.

Related Topic