• Advertisement
Sign in to follow this  

traversals

This topic is 4432 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi About 2 weeks ago I left a post on traversing a generic LinkedList in Java, and couldn't get the kind of help I was looking for. I am still having the same problem, so I will present it again if anyone is interested in helping me out. Let's say I have a class called Widget, which is a parent to several child extension classes: Thing_1,Thing_2 and Thing_3. So I create a generic LinkedList of type Widget, and then add into that list only Thing_1's, Thing_2's or Thing_3's. Observe:
class Widget { /* widget info */ }
class Thing_1 { /* thing 1 info */ }
class Thing_2 { /* thing 2 info */ }
class Thing_3 { /* thing 3 info */ }

Thing_1 a = new Thing_1();
Thing_2 b = new Thing_2();
Thing_3 c = new Thing_3();

LinkedList<Widget> widgetList = new LinkedList<Widget>();

widgetList.add(a);
widgetList.add(b);
widgetList.add(c);

Now here is where I am having problems: My objective is to be able to traverse the LinkedList of widgets and to inspect each node (each widget child), and to perform a different action on that node depending on what class-type the node is. So for instance, for the sake of the example, let's pretend I have some local variable 'localVar' that gets initialized to zero (0). Now as I traverse the list, if I find that a node is an instance of a Thing_1, I wish to increment localVar. If the node is an instance of a Thing_2, I wish to decrement localVar, and if the node is an instance of a Thing_3, I wish to reset localVar to zero. Here is the code I have been using so far, which doesn't work at all (presume I have included all of the code from above in this example as well):
// LinkedList of widgets is already populated from the code above

ListIterator<Widget> iter = widgetList.listIterator();
Widget stepNode = new Widget();
int localVar = 0;

while(iter.hasNext())
{
    // Save the next node to our step node for inspection.
    stepNode = iter.next();

    if(stepNode instanceof Thing_1)
        localVar++;

    else if(stepNode instanceof Thing_2)
        localVar--;

    else if(stepNode instanceof Thing_3)
        localVar = 0;

    else
        localVar = -1;
}

Now when I posted this several weeks ago, I heard enormous outcry from many programmers telling me that using instanceof is generally bad design. But I don't see any other way around this... Keeping my end objective in sight - to inspect each node for its class type and react differently to it - what else, besides poor design, am I doing wrong that is keeping this list from working correctly? How could I improve my code to run better, yet with the same outcome? hisDudeness

Share this post


Link to post
Share on other sites
Advertisement
Those guys who think its a bad idea probably think you should implement a base class for Thing1, Thing2 and Thing3 and then implement a virtual function that returns a value from an enum. This is precisely what instanceof does so I see no benefit to typing up code that the compiler is going to generate anyhow.

On the other hand, they might think that whatever this function does should be implemented instead in virtuals in the Thing classes. But if the task is relatively trivial and very context-specific to this list, then it seems silly to me to complexify these other classes.

People go a little overboard with virtual/abstract stuff in classes, I think. And whenever people make vague assertions like "generally this or that is bad practice", you should be on the lookout. That's frequently a good indicator of the ritual recitation of received wisdom. If your solution takes a dozen lines to code, all in one place and if the potential for future changes can be covered by a simple Assert-type test then I dare someone to explain to me how a design that scatters the same logic in 6 difference functions is preferable.

Share this post


Link to post
Share on other sites
Quote:
Original post by dalep
Those guys who think its a bad idea probably think you should implement a base class for Thing1, Thing2 and Thing3 and then implement a virtual function that returns a value from an enum. This is precisely what instanceof does so I see no benefit to typing up code that the compiler is going to generate anyhow.

I'll venture a guess and say you're mistaken. "Those guys" probably think you should ask yourself what functionality the localVar change is meant to convey, and move that into the virtual function. The code as it stands is just a less flexible version of the exact same functionality virtual functions were invented to provide. Alternatively, you can ask yourself why are are throwing three different types of objects into a single container, when you apparently need those three different types kept separate. Maybe they aren't even distict types at all, and the subclasses are just overdesign themselves? Given a toy example like this its hard to say how things may [or may not] be improved. But I just about guarentee the solution isn't a virtual function that returns a value from an enum, at least not from a design point of view.

It's been a while since I used Java, and it didn't have generics then. However, at a glance I don't notice any glaring logic errors. Thing_1 et al don't extend Widget, but that should have resulted in compile errors. What exactly is it doing that isn't right?

CM

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement