Comparable и Comparator

Рейтинг: 0Ответов: 1Опубликовано: 13.01.2023

Есть класс со сгенерированным кодом в нем поля:

public class Student implements Comparable<Student> {
    String name;
    Character sex;
    int age;
    int course;
    double avgGrade;

Имплементировал Comparable для сортировки по возрасту и хочу написать Comparator для сортировки допустим по полу.

class StudentSexComparator implements Comparator<Student>{

    @Override
    public int compare(Student st1, Student st2) {
        return st1.sex.compareTo(st2.sex);
    }
  1. Если использовать примитив (char) то сравнивать вообще не дает. Это значит что поля по которым сравниваем должен быть обязательно Оберткой?

  2. Можете подсказать почему в StudentSexComparator метод compare не дает возможности пользоваться геттерами и так ли критично если в этом случает обращаться к полям напрямую?

Ответы

▲ 2Принят

Ответ на первый вопрос уже дал в комментариях @Stanislav Volodarskiy: если поле содержит примитивное значение char, у такого типа не может быть метода compareTo, и при собственной реализации компаратора нужно будет пользоваться методом Character::compare(char a, char b).

Геттерами также никто не запрещает пользоваться:

@Getter
public class Student {
    private Character sex;
 // ...
}

class StudentSexComparator implements Comparator<Student>{

    @Override
    public int compare(Student st1, Student st2) {
        return st1.getSex().compareTo(st2.getSex());          // для Character
//      return Character.compare(st1.getSex(), st2.getSex()); // для char
    }
}

Отвечая на второй вопрос по поводу геттеров. Отдельный класс для компаратора с деталями реализации можно вообще пропустить при использовании ссылок на соответствующий геттер класса Student:

Comparator<Student> bySex = Comparator.comparing(Student::getSex);

Аналогично, можно воспользоваться методом, сравнивающий примитив:

Comparator<Student> bySexPrim = Comparator.comparingInt(Student::getSex);

В зависимости от того, как определён тип, возвращаемый геттером (char или Character), автоматически будет применяться boxing/unboxing.