Всем привет!
Сегодня предлагаю рассмотреть данную тему, так как она нередко "всплывает" как на практике, так и на технических интервью.
Немного из теории
1. Чтобы объекты нашего класса E можно было сравнить и сортировать, он должен имплементить интерфейс Comparable, который содержит метод int compareTo(E other), для сравнения текущего объекта с объектом, переданным в качестве параметра.
2. Если в классе E, который мы хотим использовать не реализован интерфейс Comparable, или реализовал, но нас не устраивает его функциональность, то можем создать класс, реализующий Comparator<E>, определить метод compare(E o1, E o2), позволяющий сравнивать между собой 2 объекта.
3. Методы compareTo и compare возвращают: - 0, если значения равны; - отрицательное значение (обычно -1), если первый объект меньше второго; - положительное значение (обычно +1), если первый объект больше второго.
К примерам
Пример 1. Реализация Comparator<Integer> Нередко в интернете (да и что греха таить в пулл реквестах на проектах) натыкаюсь на такой пример реализации:
На первый взгляд "не ну а чего такого-то?", но потом этим компоратором пытаемся отсортировать список, например: [2, 2147483647, 35, null, -2147483648, 16] и получаем:
- переполнение типа
- NullPointerException
Про NPE стоит однако отметить отдельно. В некоторых случаях известно и даже гарантировано, что значения не могут быть null, и проблем не возникнет. Но часто null значения допустимы по условиям задачи, и нужно предусматривать их обработку. Чаще всего null значения при сортировке выводят либо в начало списка либо в конец. Также иногда null значения можно смапить в число (например в 0), если это допустимо условиями задачи.
Перепишем компоратор, учитывая обработку null (пусть они всегда будут в конце списка) и заменив вычитание на сравнение:
Проверяем:
Пример 2. Сортировка по двум полям. Данный пример предлагаю реализовать через Comparable. Для нашего примера возьмем класс:
Имплементим Comparable<Player> и реализуем метод compareTo так, чтобы сравнение было сначала по полю name (ascending), затем по полю age (descending):
Выполним сортировку:
Результат:
Исходный код примеров:
https://gist.github.com/onakrainikoff/5f822a8fca4b4edf39db0d3390d4751c https://gist.github.com/onakrainikoff/b95157d1d76bd75c325ffe9dd74effd7
Также подписывайтесь на
мой telegram: https://t.me/onakrainikoff
мой github https://github.com/onakrainikoff