The Java Course provides a general introduction to programming in Java. It is based on A.B. Downey's book, How to Think Like a Computer Scientist. Click here for details.


The Golfer Class

Finally, let's looks at how we can make a new class that belongs to Comparable. As an example of something with an unusual definition of "highest" priority, we'll use golfers:

public class Golfer implements Comparable {
    String name;
    int score;

    public Golfer (String name, int score) {
        this.name = name;
        this.score = score;
    }
}

The class definition and the constructor are pretty much the same as always; the difference is that we have to declare that Golfer implements Comparable. In this case the keyword implements means that Golfer implements the interface specified by Comparable.

If we try to compile Golfer.java at this point, we get something like "class Golfer must be declared abstract. It does not define int compareTo(java.lang.Object) from interface java.lang.Comparable." In other words, to be a Comparable, Golfer has to provide a method named compareTo. So let's write one:

    public int compareTo (Object obj) {
        Golfer that = (Golfer) obj;

        int a = this.score;
        int b = that.score;

        // for golfers, low is good!
        if (a<b) return 1;
        if (a>b) return -1;
        return 0;
    }

Two things here are a little surprising. First, the parameter is an Object. That's because in general the caller doesn't know what type the objects are that are being compared. For example, in PriorityQueue.java when we invoke compareTo, we pass a Comparable as a parameter. We don't have to know whether it is an Integer or a Golfer or whatever.

Inside compareTo we have to convert the parameter from an Object to a Golfer. As usual, there is a risk when we do this kind of cast: if we cast to the wrong type we get an exception.

Finally, we can create some golfers:

        Golfer tiger = new Golfer ("Tiger Woods", 61);
        Golfer phil = new Golfer ("Phil Mickelson", 72);
        Golfer hal = new Golfer ("Hal Sutton", 69);

And put them in the queue:

        pq.insert (tiger);
        pq.insert (phil);
        pq.insert (hal);

When we pull them out:

        while (!pq.empty ()) {
            golfer = (Golfer) pq.remove ();
            System.out.println (golfer);
        }

They appear in descending order (for golfers):

        Tiger Woods     61
        Hal Sutton      69
        Phil Mickelson  72

When we switched from Integers to Golfers, we didn't have to make any changes in PriorityQueue.java at all. So we succeeded in maintaining a barrier between PriorityQueue and the classes that use it, allowing us to reuse the code without modification. Furthermore, we were able to give the client code control over the definition of compareTo, making this implementation of PriorityQueue more versatile.



Last Update: 2011-01-24