Компаратор работает для моего ArrayList, но код выглядит неправильно?

1

У меня есть объект ArrayList, называемый курсом, и я пытаюсь сортировать его двумя способами: по курсуID и времени начала курса.

class Course implements Comparable<Course> {
    private int courseID;
    private String courseBeginTime;

    // implement the compareTo method defined in Comparable
    @Override
    public int compareTo(Course course) {
        if (getCourseID() > course.getCourseID()){
            return 1;
        } else if(getCourseID() < course.getCourseID()){
            return -1;
        } else {
            return 0;
        }       
    }

Тогда у меня есть эти компараторы:

//implement the comparators
class IDSorter implements Comparator<Course> {
    public int compare(Course course1, Course course2) {
        return Integer.compare(course1.getCourseID(), course2.getCourseID());
    }
}

class startTimeSorter implements Comparator<Course> {
    public int compare(Course course1, Course course2) {
        return Integer.compare(Integer.parseInt(course1.getCourseBeginTime()),
                Integer.parseInt(course2.getCourseBeginTime()));
    }
}

Я сортирую их по своему основному методу следующим образом:

Collections.sort(courseList, new IDSorter());
Collections.sort(student.getStudentSchedule(), new StartTimeSorter());

Код работает, я могу получить список, отсортированный по ID или startTime.... но я не понимаю, почему. В классе Course метод compareTo сравнивает только getCourseID.

Как работает StartTimeSorter, которому нужно сравнить курсBeginTime?

Как я могу переписать, чтобы иметь больше смысла?

Теги:
arraylist

4 ответа

2
Лучший ответ

Если класс реализует Comparable, это считается естественным упорядочением этого класса. Это упорядочение используется, когда вы не даете явный Comparator to Collections.sort. Поэтому единственная аргументация сортировки принимает List<T> где T extends Comparable<? super T> T extends Comparable<? super T>. Две версии аргументов берут List<T> без ограничений на T и Comparator<? super T> Comparator<? super T>. Поэтому Course.compareTo не используется в вашем примере.

  • 0
    Мог бы я отсортировать его двумя разными способами, не используя тогда свой собственный компаратор? Мне кажется глупым, что я переопределил метод CompareTo, даже если мне не нужно его использовать, но компилятор предупреждает меня, что мне все равно нужно его реализовать.
  • 0
    Либо IDSorter, либо реализующий Comparable является избыточным. StartTimeSorter все еще будет необходим. Я бы придерживался двух компараторов, если бы все заказы рассматривались одинаково.
Показать ещё 2 комментария
1

Существует два варианта метода Collections.sort. Один принимает один аргумент как набор объектов Comparable. Другой принимает два аргумента: во-первых, второй сбор является компаратором. Вы использовали второй вариант. Следовательно, метод compareTo не используется.

  • 0
    Понятно, поэтому я получаю в основном код в моем методе CompareTo не используется. Так что в этом случае, когда я не использую CompareTo, я все еще должен реализовать его, в противном случае компилятор предупреждает меня, что мне нужно это реализовать. Как стандартная практика, какой код я должен вставить туда, если я его не использую? Я должен вернуть что-то для метода CompareTo.
  • 0
    Вам не нужно реализовывать это, так как вам не нужно реализовывать Comparable интерфейс.
1

Если вы укажете Comparator в методе Collections.sort, это учтет это, несмотря на то, что класс реализует Comparable. Попробуйте выполнить сортировку без передачи Comparator в методе сортировки, вы увидите, чего вы ожидаете, т.е. Метод compareTo.

  • 0
    Спасибо, теперь я понимаю. Так что, если я использую свой собственный Comparator, то я даже не использую метод CompareTo. Тогда что я должен кодировать в метод CompareTo? Мне нужно реализовать это, так как я объявляю, что Course реализует Comparable <Course>
  • 0
    Есть два способа сравнить ваши классы. Один - позволить классу реализовать Comparable, другой - передать Comparator в методе сортировки Collections. Последнее предпочтительнее, потому что вы не привязываете только одну логику сравнения к классу, но можете сортировать свой класс несколькими способами, передавая различные реализации компаратора.
0

Я думаю, что ваш метод compareTo должен быть таким:

@Override
public int compareTo(Course course) {
    if (getCourseID() > course.getCourseID()){
        return 1;
    } else if(getCourseID() < course.getCourseID()){
        return -1;
    } else {
        return Integer.compare(Integer.parseInt(getCourseBeginTime()),
            Integer.parseInt(course.getCourseBeginTime()));
    }       
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню