Упорядочивание списка по убыванию поля int, а затем лексикографически, если поле int равно

Я немного запутался в том, как реализовать comparators/comparable. Я пытаюсь отсортировать список (в настоящее время ArrayList, но это может измениться...), в результате чего при вызове Collections.Sort его объекты сортируются по определенному целочисленному полю в порядке убывания, и если это целочисленное поле равно, то по лексикографическому порядку поля имени.

Это мой объект:

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;
}
}

На данный момент он сортирует только по числовым полям. Как мне сделать сортировку по лексикографическому порядку, если числовые поля равны?

Меня немного смущает метод compareTo. Это определяет естественный порядок, верно? Так что же

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

на самом деле делать? Большое вам спасибо за вашу помощь!

РЕДАКТИРОВАТЬ:

Я получил желаемый результат, добавив оператор if в метод сравнения и вернув arg0.compareTo(arg1). Однако я все еще не уверен в методе compareTo (даже после прочтения в сети), и простое объяснение было бы здорово.


person Ofek    schedule 09.04.2014    source источник


Ответы (2)


Меня немного смущает метод compareTo. Это определяет естественный порядок, верно? Так что же

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

на самом деле делать?

Естественный порядок строк — это их лексикографический порядок.

пытаться:

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

Вы можете использовать следующий шаблон для определения compareTo со все более и более конкретными условиями:

@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;
}
person Oleg Estekhin    schedule 09.04.2014
comment
Вам нужно будет использовать Integer.compare(other._time, this._time), поскольку OP хочет порядок по убыванию. - person Puce; 09.04.2014