Implementing custom compareTo

2019-03-31 12:38发布

@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?

4条回答
爷的心禁止访问
2楼-- · 2019-03-31 13:26

Apache CompareToBuilder class is worth a mention.

You can implement with or without reflection

public int compareTo(Object o) {
    return CompareToBuilder.reflectionCompare(this, o);
}
查看更多
男人必须洒脱
3楼-- · 2019-03-31 13:32

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).

查看更多
Animai°情兽
4楼-- · 2019-03-31 13:37

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

查看更多
Anthone
5楼-- · 2019-03-31 13:40

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.

查看更多
登录 后发表回答