Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a compareTo to a Generic Class that Implements Comparable

Tags:

I have a Generic Class with two type variables, which implements java.lang.Comparable.

public class DoubleKey<K,J> implements Comparable<DoubleKey<K,J>>{

    private K key1;
    private J key2;

    public DoubleKey(K key1, J key2){
        this.key1 = key1;
        this.key2 = key2;
    } 

    public K getFirstKey(){
        return this.key1;
    }

    public J getSecondKey(){
        return this.key2;
    }

    // need for Comparable interface
    public int compareTo(DoubleKey<K,J> aThat){
        ...
    }

}

Becuase i implemeted it with Comparable, I need to write the compareTo() method. Because K, J can be of ANY type, I'm having problems on how to compare them completely. Is there a way to be able to catch all possible types (Primitive, Wrapper, Object) in the comparison? Thanks for the help!

like image 638
John Bautista Avatar asked Feb 16 '11 08:02

John Bautista


People also ask

Do you need to implement comparable to use compareTo?

Comparable interface has a single abstract method compareTo() that objects need to implement to have a natural ordering. The objects must be mutually comparable and must not throw ClassCastException for any key in the collection.

How does compareTo work in comparable?

The compareTo() method works by returning an int value that is either positive, negative, or zero. It compares the object by making the call to the object that is the argument. A negative number means that the object making the call is “less” than the argument.

How do you make the class you define comparable?

To make an object comparable, the class must implement the Comparable interface. negative , if this object is less than the supplied object. zero , if this object is equal to the supplied object. positive , if this object is greater than the supplied object.


2 Answers

so to summarize the said above and to puzzle it together into a working code this is:

    public class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>
        implements Comparable<DoubleKey<K, J>> {

    private K key1;
    private J key2;

    public DoubleKey(K key1, J key2) {
        this.key1 = key1;
        this.key2 = key2;
    }

    public K getFirstKey() {
        return this.key1;
    }

    public J getSecondKey() {
        return this.key2;
    }

    public int compareTo(DoubleKey<K, J> that) {

        int cmp = this.getFirstKey().compareTo(that.getFirstKey());
        if (cmp == 0)
            cmp = this.getSecondKey().compareTo(that.getSecondKey());
        return cmp;
    }
}
like image 151
olippuner Avatar answered Oct 18 '22 10:10

olippuner


Would you like to introduce a requirement that K and J have a natural ordering that you can use? In this case you can declare your class DoubleKey like this:

class DoubleKey<K extends Comparable<K>, J extends Comparable<J>>

You can then define your DoubleKey's compareTo as you like. You can do things like:

getFirstKey().compareTo(aThat.getFirstKey())

You can't compare any instance of K to an instance of J, though. There is no ordering defined over those types.

If these types don't necessarily have a natural ordering (many don't), you can take a Comparator<K> and Comparator<J> as parameters to the constructor of your DoubleKey. A class that does this already that you can use as an example is Google Guava's excellent Maps class (see specifically the newTreeMap methods and the bounds of the types they accept).

like image 41
sjr Avatar answered Oct 18 '22 10:10

sjr