0

Can I use a compareTo() method with a second argument to sort objects by different variables, or should I use some other method?

For example:

public class Girl implements Comparable<Girl> {

    private String fName;
    private String lName;
    private int hotness;

    public Girl () {} // blah blah constructor

    @Override
    public int compareTo (Girl g, int order) {
        if (order == 1) // then sort by first name
        if (order == 2) // then sort by last name
        if (order == 3) // then sort by hotness
    }
}
2
  • In this case it is better if you use Comparator Commented Nov 29, 2013 at 6:58
  • 1
    An important point to remember is that comparisons must agree in both directions, so you'd have to use the order attribute of the other object too. Commented Nov 29, 2013 at 6:59

3 Answers 3

2

No, you can't. You'll find that code doesn't compile -- the @Override annotation says that compareTo(Girl, int) must be declared in a superclass or interface, but it's not! Comparable<Girl> defines only compareTo(Girl).

Instead, you should use a Comparator<Girl> for each ordering. This is a class that provides its own compareTo that takes two girls. You can then create different comparators, and pass the appropriate one to the function that needs it. In other words, remove the order field from Girl, and instead implement the different orderings as different instances of a Comparator<Girl>.

Most classes or functions that take a T extends Comparable<T> also have versions that take a T and a Comparator<T>. One example of this is Collections.sort. Another is TreeSet, which can take a comparator at construction time.

If that seems annoying or pedantic, think about how you would use such a function. Let's say your function takes a T extends Comparable<T>. You try to compare two of these by calling item1.compareTo(item2), according to that Comparable interface. If your code compiled, that method wouldn't exist! Note that Java doesn't have default parameters, so there's no way to say "if they don't pass in the int order, assume it's 0."

Sign up to request clarification or add additional context in comments.

Comments

1

You are not overriding the compareTo method, but overloading it. And marking with @Override won't allow to compile the class.

Use multiple Comparator classes to compare Girls based on dirrent scenarios.

7 Comments

+1 for the instance variable although you should show it as a parameter when constructing the class.
-1 This is actually a very dangerous idea, and it violates the Comparable contract. What if you have one girl instantiated with order = 1, and a second one order = 2? In that case, you could have girl1.compareTo(girl2) > 0 and girl2.compareTo(girl1) > 0. This means that there is not a total ordering on Girl, which the Comparable interface requires. A lot of code will likely break.
I agree with @yshavit. I take back my upvote (if I could). I thought the code was creating a custom comparator. I wasn't wearing my glasses :)
@Yshavit : He won't use order to compare the Girls, it's only used as a base for comparing. whether need to be sorted with fname or lname.
Imagine ada = new Girl("Ada", "Lovelace", 2) and frances = new Girl("Frances E.", "Allen", 1). ada.compareTo(frances) will use Amanda's ordering of last name, meaning that it will return > 0 ("Lovelace" comes after "Allen"). frances.compareTo(ada) will use Frances' ordering of first name, meaning it will also return > 0 ("Frances" comes after "Ada").
|
0

No, what you're trying to do won't work, as you're not overriding the compareTo() method. An alternate solution here can be to use Collections.sort() to sort your collections with a custom comparator and use the order variable in it(it has to be made final to be able to use it in that). Something like this.

void inSomeMethod() {
    final int order = 0; // has to be final
    Collections.sort(new ArrayList<Girl>(), new Comparator<Girl>() { // for example

        @Override
        public int compare(Girl o1, Girl o2) {
            if (order == 1) // then sort by first name
            if (order == 2) // then sort by last name
            if (order == 3) // then sort by hotness
            return 0;
        }
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.