Sign in to follow this  
plywood

stumped stupid

Recommended Posts

[Java:] I am in between a rock and a hard place here. I have an ArrayList of, say, Widget types. Because of my implementation, after I add a new Widget into the ArrayList (using add() method), I want to sort the Widget array list, based on the value returned from Widget's calcFoo() method. Observe: Widget w; // Within a loop: w = new Widget(5,3,5, 'f'); // whatever list.add(w); Widget.sort(list); // sorted in ascending order based on calcFoo() return val Because of bad design, this is the implementation I have to stick with. Of great importance, note that Widget implements Comparable, and so I have written the compareTo() heading defined in the Comaparable interface. Thus, the sort function actually calls the compareTo method to make the sorting comparisons. Now then, onto my problem. See, Widget is actually an abstract base class for many children (the code example above was just for show). So I add a new Widget child onto the ArrayList, and it is now at the 'top' of the list. In order to sort it, I need to be able to compare the return value of its calcFoo() method with the return values of the calcFoo's of every other widget currently on the list, find which two Widget's it belongs between, and then somehow swap it into the right place. I am not at all familiar with collections, and especially, iterator objects, and I am afraid that perhaps what i am proposing here is, indeed, impossible to accomplish. :-/ any input here will go along way. I tried to make some sense out of everything using the java api docs, but they only confused me more. thanks, ply

Share this post


Link to post
Share on other sites
This will be taken care of this for you automatically. compareTo() in the base class doesn't need to be overridden or anything. What will happen is that every time sort() wants to compare two Widgets 'a' and 'b', it will see that they are Widgets and call a.compareTo(b). The superclass compareTo() will in turn call calcFoo() on both a and b, and compare the results (I assume calcFoo() returns something simple, such as an int). This call will be virtual; i.e. if 'a' is really a Sprocket and 'b' is a Gadget (both extending Widget), then a and b still get their derived-class-specific calcFoo() called, and the results are compared. So as long as calcFoo() can be defined in such a way that it makes sense to compare a Sprocket's foo to a Gadget's foo (and order the two Widgets according to the results), everything is just fine.

All you do is write Widget.compareTo(Object o) so that it uses the .calcFoo() results from 'this' and 'o'. (With the appropriate casting etc. of 'o', of course. Unless of course you're using Java 1.5 generics.)

Oh, wait. You seem to be assuming that you need to write the sort yourself - i.e. you have a sort(ArrayList a) method as a static member of the Widget class. Don't do that. The standard library provides for this - the ArrayList already has a .sort() method (no parameter, for the normal case), defined in the List interface, IIRC. Or you could use Collections.sort().

Or did you mean that you want to implement multiple sort orderings, or a sort ordering that's not based on the "natural" comparison of Widgets? In that case, you'll want to look into extending the Comparator class, and passing an instance of a ByFooComparator to the sort() method.

Or did you mean that you want to avoid sorting after every element insertion? In that case, try using a sorted container instead - IIRC, TreeMap is one such beast.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this