Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2006

Tip: Looking for answers? Try searching our database.

Implementing the compareTo method

Thread view: 
Paul Morrison - 09 Jan 2006 19:10 GMT
Hi,

I have written an Edge class that takes two Point values as parameters and I
want to make the class implement comparable but I dont know how to do it.
This is what I have got so far:

public class Edge implements Comparable<Edge> {
     Point point1;
     Point point2;
     double ymin, ymax, xvalue, oneoverm;

     Edge(Point point1, Point point2) {
         this.point1 = point1;
         this.point2 = point2;
         .......
    public Edge compareTo(Edge e) {
         //to do
     }

I want to sort the edges in order of their ymin values, would I be correct
in thinking that I do something along the lines of:

if (edge.ymin < e.ymin)
   return edge;
else
   return e;

Is this on the right lines?

Cheers

Paul
James Westby - 09 Jan 2006 20:07 GMT
> Hi,
>
[quoted text clipped - 28 lines]
>
> Paul

Yeah that's the idea, but you want to use the instance variables of the
object somewhere, so your edge.ymin should probably be this.ymin.

James
Paul Morrison - 09 Jan 2006 20:16 GMT
>>      public Edge compareTo(Edge e) {
>>           //to do
[quoted text clipped - 7 lines]
>> else
>>     return e;

> Yeah that's the idea, but you want to use the instance variables of the
> object somewhere, so your edge.ymin should probably be this.ymin.

I have just looked, and it seems that the return type of compareTo has to be
int. What exactly do I return?

Paul
James Westby - 09 Jan 2006 20:22 GMT
>>>     public Edge compareTo(Edge e) {
>>>          //to do
[quoted text clipped - 15 lines]
>
> Paul

Ah yes, sorry, the Javadoc states

'Returns a negative integer, zero, or a positive integer as this object
is less than, equal to, or greater than the specified object.'

so

if this.ymin < e.min return -1
else if this.ymin > e.min return 1
else return 0

The other thing to note is that it is defined as compareTo(Object o), so
you want to make a cast from the parameter first. The method is defined
to throw a ClassCastException if the type is not correct.

See http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Comparable.html 
for more info

Also as ymin is a double you shouldn't expect this method to return 0,
but it might in some cases.

James

James
Googmeister - 09 Jan 2006 20:57 GMT
> The other thing to note is that it is defined as compareTo(Object o), so
> you want to make a cast from the parameter first. The method is defined
> to throw a ClassCastException if the type is not correct.

Or you can use generics as the OP does and avoid the cast.

> Also as ymin is a double you shouldn't expect this method to return 0,
> but it might in some cases.

You should absolutely expect this method to return 0 in some cases,
e.g., e.compareTo(e).
James Westby - 09 Jan 2006 21:06 GMT
>>The other thing to note is that it is defined as compareTo(Object o), so
>>you want to make a cast from the parameter first. The method is defined
[quoted text clipped - 7 lines]
> You should absolutely expect this method to return 0 in some cases,
> e.g., e.compareTo(e).

Absolutely, sorry, when I wrote this I thought I had phrased it badly,
and I obviously did. What i meant was that his code shouldn't rely on
e.compareTo(f) == 0 for some e != f. I should have been more specific,
thanks for pointing it out.
Paul Morrison - 09 Jan 2006 20:25 GMT
I will expand on what I am doing as there may be an easier way to do this. I
have an ArrayList which holds ArrayLists of 4 numbers. I want the sort the
second ArrayList in order of the first item in that ArrayList, going from
lowest to highest.

I.e.

ArrayList -> ArrayList ->     ymin
                                           ymax
                                           xvalue
                                           1/m

I was looking at writing a loop, going through each ArrayList and comparing
the first element of each, each time keeping the minimum one, but I feel
that this will be inefficient.

Hope this makes things clearer.

Paul

>>>      public Edge compareTo(Edge e) {
>>>           //to do
[quoted text clipped - 15 lines]
>
> Paul
James Westby - 09 Jan 2006 20:44 GMT
> I will expand on what I am doing as there may be an easier way to do this. I
> have an ArrayList which holds ArrayLists of 4 numbers. I want the sort the
[quoted text clipped - 15 lines]
>
> Paul

Can i ask why you are using an ArrayList to store those four numbers? Is
it always four numbers?

James
Paul Morrison - 09 Jan 2006 20:53 GMT
> Can i ask why you are using an ArrayList to store those four numbers? Is
> it always four numbers?

Yes it is always four numbers. I am using an ArrayList rather than an array
as I am more comfortable with these, not for any other reason. Would it be
easier to do this with another Collection type?

Paul

PS Sorry for replying directly, wrong button!
James Westby - 09 Jan 2006 21:02 GMT
>>Can i ask why you are using an ArrayList to store those four numbers? Is
>>it always four numbers?
[quoted text clipped - 6 lines]
>
> PS Sorry for replying directly, wrong button!

Well there's nothing wrong with it, but one use Collections is when you
don't know how many elements there are ahead of time.

You could use an ArrayList of objects that you define, implement
Comparable on these objects, then use Colections.sort, but then again an
object to hold four numbers may be a bit much. The natural way would be
to use arrays.

To do it your way have a look at this, the code needs tidying up to deal
with cases where you don't get exactly what you want, but this runs and
shows the concept. It's a JUnit test case, but you could wrap it all in
a main() instead if you wanted. The key is the Comparator that
Collections.sort allows you to provide. Also it will be a lot neater if
you are using 1.5 (which I think you are).

James

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import junit.framework.TestCase;

/**
 * @author jw2328
 *
 */
public class ArrayListTest extends TestCase {

    public void testNothing() {

        List a = new ArrayList();

        List b = new ArrayList();

        b.add(new Integer(1));
        b.add(new Integer(2));

        List c = new ArrayList();

        c.add(new Integer(3));
        c.add(new Integer(4));

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

        Iterator it = a.iterator();

        while (it.hasNext()) {
            System.out.println(((ArrayList) it.next()).get(0));
        }

        Collections.sort(a, new Comparator() {

            public int compare(Object o1, Object o2) {
                Integer a = (Integer) ((ArrayList) o1).get(0);
                Integer b = (Integer) ((ArrayList) o2).get(0);
                return a.compareTo(b);
            }
        });

        System.out.println("Sorted:");

        it = a.iterator();

        while (it.hasNext()) {
            System.out.println(((ArrayList) it.next()).get(0));
        }

    }

}
Oliver Wong - 09 Jan 2006 21:04 GMT
>> Can i ask why you are using an ArrayList to store those four numbers? Is
>> it always four numbers?
[quoted text clipped - 3 lines]
> as I am more comfortable with these, not for any other reason. Would it be
> easier to do this with another Collection type?

   You might want to define a class to encapsulate these for values. For
example:

<code>
class Edge implements Comparable<Edge> {
 double yMin, yMax, xValue, inverseM;

 /*Implement the compareTo method here*/
}

ArrayList<Edge> myFoos = new ArrayList<Edge>();
</code>

   - Oliver
Paul Morrison - 09 Jan 2006 21:34 GMT
>    You might want to define a class to encapsulate these for values. For
> example:
[quoted text clipped - 8 lines]
> ArrayList<Edge> myFoos = new ArrayList<Edge>();
> </code>

I have done the final part, ie adding <Edge> to my initialisation of the
ArrayList, but when I call, for example, myFoos.add(...) I get an error when
compiling:

   cannot find symbol method(java.util.ArrayList)

Any idea why this would happen? It compiled before I changed it. Could it be
that I initialise the ArrayList before I create the Edge class?

Paul
Oliver Wong - 09 Jan 2006 22:01 GMT
>>    You might want to define a class to encapsulate these for values. For
>> example:
[quoted text clipped - 17 lines]
> Any idea why this would happen? It compiled before I changed it. Could it
> be that I initialise the ArrayList before I create the Edge class?

   I don't know why you are getting this error. This code compiles find for
me:

<SSCCE>
import java.util.ArrayList;

public class Edge implements Comparable<Edge> {

 double yMin, yMax, xValue, inverseM;

 public int compareTo(Edge arg0) {
   if (this.yMin < arg0.yMin) {
     return -1;
   }
   if (this.yMin > arg0.yMin) {
     return 1;
   }
   return 0;
 }

 public static void main(String args[]) {
   ArrayList<Edge> myFoos = new ArrayList<Edge>();
   myFoos.add(new Edge());
 }
}
</SSCCE>

   - Oliver
Roedy Green - 09 Jan 2006 22:27 GMT
>Yes it is always four numbers. I am using an ArrayList rather than an array
>as I am more comfortable with these, not for any other reason. Would it be
>easier to do this with another Collection type?

for a fixed known number of elements, an array is the way to fly. They
are much faster and the type safety is not nearly so flaky.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Raymond DeCampo - 10 Jan 2006 16:05 GMT
>>Yes it is always four numbers. I am using an ArrayList rather than an array
>>as I am more comfortable with these, not for any other reason. Would it be
>>easier to do this with another Collection type?
>
> for a fixed known number of elements, an array is the way to fly. They
> are much faster and the type safety is not nearly so flaky.

...and you can use Arrays.asList() for interoperability with collections.

HTH,
Ray

Signature

This signature intentionally left blank.

zero - 09 Jan 2006 20:35 GMT
> I have just looked, and it seems that the return type of compareTo has
> to be int. What exactly do I return?
>
> Paul

if edge1 is "smaller" than edge2, return a negative value
if edge1 and edge2 are equal, return 0
if edge1 is "greater" than edge2, return a positive value

The exact value depends solely on your implementation.  A possible
implementation could be:

final double PRECISION = 100.0;

return (int)((e.ymin - this.ymin) * PRECISION);

Here you can use PRECISION to manipulate the precision of the comparison.  
This may be necessary if you're comparing values that are close to
eachother.

Signature

Beware the False Authority Syndrome

Googmeister - 09 Jan 2006 21:00 GMT
> > I have just looked, and it seems that the return type of compareTo has
> > to be int. What exactly do I return?
[quoted text clipped - 15 lines]
> This may be necessary if you're comparing values that are close to
> eachother.

Don't do these floating point hacks - you'll break the transitivity
part of the compareTo() contract.
Roedy Green - 09 Jan 2006 22:10 GMT
>I have written an Edge class that takes two Point values as parameters and I
>want to make the class implement comparable but I dont know how to do it.
>This is what I have got so far:

see http://mindprod.com/jgloss/comparable.html
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Paul Morrison - 10 Jan 2006 19:18 GMT
> I have written an Edge class that takes two Point values as parameters and
> I want to make the class implement comparable but I dont know how to do
> it. This is what I have got so far:

OK, I have written a compareTo method as follows:

public int compareTo(Edge e) {
         if (this.ymin < e.ymin)
             return -1;
         else if (this.ymin > e.ymin)
             return 1;
         else
             return 0;
}

I then try to sort an ArrayList of Edges by calling:

edgeTable.sort();

but I get the error:

C:\AETFillAlgorithm.java:73: cannot find symbol
symbol  : method sort()
location: class java.util.ArrayList
     edgeTable.sort();

I thought that once I had written the compareTo method I would be able to
sort an ArrayList of type Edge. Is there more that I must do?

Paul
James Westby - 10 Jan 2006 19:28 GMT
>>I have written an Edge class that takes two Point values as parameters and
>>I want to make the class implement comparable but I dont know how to do
[quoted text clipped - 26 lines]
>
> Paul

If you look there is no sort method on ArrayList, you must use

Collections.sort(edgeTable);

This will then use your compareTo method to do the sort.

James
Paul Morrison - 10 Jan 2006 19:34 GMT
> If you look there is no sort method on ArrayList, you must use
>
> Collections.sort(edgeTable);
>
> This will then use your compareTo method to do the sort.

Thank you James (and all others who helped), your help is much appreciated!

Paul


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.