Ordering a list via descending order of int field and then lexicographically if int field is equal

StackOverflow https://stackoverflow.com/questions/22956562

سؤال

I am a little confused about how to implement comparators/comparable. I am trying to sort a list (currently an ArrayList, but this is can change...) whereby when Collections.Sort is called, it's objects are sorted by a specific integer field in descending order, and if that integer field is equal then by lexicographic order of the name field.

This is my object:

class Movie implements Comparator<Movie>, Comparable<Movie> {
public String _title;
public int _time;

public Movie(String title, int time) {
    this._title = title;
    this._time = time;
}

public Movie() {

}

@Override
public int compareTo(Movie o) {
    return (this._title.compareTo(o._title));
}

@Override
public int compare(Movie arg0, Movie arg1) {
    return (arg0._time > arg1._time) ? -1 : (arg0._time == arg1._time) ? 0 : 1;
}
}

At the moment it only sorts via the number fields. How do I go about making it sort via lexicographic order if the number fields are equal?

I am a little confused by the compareTo method. This defines the natural order right? So what does

 (this._title.compareTo(o._title))

actually do? Thank you so much for your help!

EDIT:

I got my desired output by adding an if statement in the compare method and returning "arg0.compareTo(arg1)". However I am still unsure as to the compareTo method (even after reading about on the net) and a simple explanation would be great.

هل كانت مفيدة؟

المحلول

I am a little confused by the compareTo method. This defines the natural order right? So what does

(this._title.compareTo(o._title))

actually do?

The natural order of Strings is their lexicographical order.

try:

if (arg0._time > arg1._time){
   return -1
} else if (arg0._time < arg1._time){
   return 1;
} else {
   return arg0._title.compareTo(arg1._title);
}

نصائح أخرى

You can use the following pattern to define compareTo with more and more specific conditions:

@Override
public int compareTo(Movie other) {
    int result = Integer.compare( this._time, other._time );

    if (result == 0) {
        result = this._title.compareTo( other._title );
    }

    if (result == 0) {
        // result = compare even more specific field
    }

    return result;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top