Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing custom compareTo

Tags:

java

compareto

@Override
public int compareTo(Object t) 
{
    if(t instanceof Student)
    {
        Student s = (Student)t;
        return (this.name.compareTo(s.name));
    }
    else
        return -1;
}

This is my compareTo method implementation for comparing two Student objects based on their name. Is it possible to compare two such objects based on multiple fields i.e., both name and age?

like image 618
Anjan Baradwaj Avatar asked Sep 12 '13 07:09

Anjan Baradwaj


4 Answers

Yes, but first you should type the Comparable interface you're implementing. Here's what it should look like:

public class Student implements Comparable<Student> {
    private int age;
    private String name;
    @Override
    public int compareTo(Student s) {
        if (name.equals(s.name))
            return age - s.age;
        return name.compareTo(s.name));
    }
}

Notice how with the typed interface Comparable<Student>, instead of the raw type Comparable, there's no need to cast.

like image 178
Bohemian Avatar answered Oct 07 '22 10:10

Bohemian


Yes it is possible to compare two objects based on different sort sequences using Comparator interface compare method.

You need to create a sort sequence class. Sorting user defined objects using comparator

like image 35
Prasad Kharkar Avatar answered Oct 07 '22 10:10

Prasad Kharkar


Note that you are overloading the compareTo method in your above code, not overriding it.

The interface you are implementing:

public interface Comparable<T> {
    public int compareTo(T o);
}

Your implementation:

@Override
public int compareTo(Object t) {
    //...
}

The original author of this interface, Josh Bloch, advised in his book Effective Java to use the @Override annotation just for this reason; bugs caused by overloading can be rather hard to spot.

You say you want to compare these objects "based on multiple fields"- I'm not sure if this means "order them one way based on two fields" or "order them multiple ways, each based on a single field". Either are possible, as demonstrated in the other answers here.

However, this is the bottom line:

You should implement Comparable<T> if you are creating a class yourself, as you appear to be, and want to define a "natural ordering" for this class. If you want to define multiple orderings or you do not control the class in question, define your own ordering in a class that implements Comparator<T> (See here).

like image 27
varzeak Avatar answered Oct 07 '22 08:10

varzeak


Apache CompareToBuilder class is worth a mention.

You can implement with or without reflection

public int compareTo(Object o) {
    return CompareToBuilder.reflectionCompare(this, o);
}
like image 1
kervin Avatar answered Oct 07 '22 08:10

kervin