From cfbcc9ebfd8f915878b757b80bad55df430f114e Mon Sep 17 00:00:00 2001 From: egorzhurov Date: Sat, 11 May 2024 12:25:36 +0300 Subject: [PATCH] Move 38 article to markdown format --- .../038/Comparable and Comparator.md | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 lessons/java-core/038/Comparable and Comparator.md diff --git a/lessons/java-core/038/Comparable and Comparator.md b/lessons/java-core/038/Comparable and Comparator.md new file mode 100644 index 0000000..539eb46 --- /dev/null +++ b/lessons/java-core/038/Comparable and Comparator.md @@ -0,0 +1,83 @@ +# Механизмы сравнения. Comparable и Comparator + +В разработке периодически возникают ситуации, когда требуется произвести сравнение объектов. Чаще всего – для сортировки +в рамках коллекции, реже – в условных конструкциях (там обычно хватает более простых выражений). + +В целом, мы знакомы с операторами сравнения `«>»` и `«<»`. Но вот незадача: они работают лишь для примитивных типов (и +то не для всех). Мы не можем использовать эти операторы для сравнения объектов целиком. + +Для решения возникшей проблемы в Java существуют 2 интерфейса: `Comparable` и `Comparator`. Как переопределенный +метод `equals()` реализует `«==»` на максималках, позволяя определять равенство объектов, так и реализации `Comparable` +и `Comparator` реализуют гибкое сравнение, заменяя собой сразу 3 отношения: `«>»`, `«<»` и `«==»`. + +Предлагаю ознакомиться с синтаксисом и примерами применения посредством +[статьи](https://metanit.com/java/tutorial/5.6.php) ниже. Там упоминается незнакомая нам коллекция типа `Set`, но в +рамках статьи она не на что не влияет, можно проигнорировать ее упоминания, а примеры адаптировать под использование +списка и вызов у него метода сортировки (будет даже нагляднее) + +На что стоит обратить внимание: + +1. Связь возвращаемого из `compareTo()`/`compare()` целочисленного значения и привычных нам `«>»`, `«<»` и `«==»`: + - `«>»` равносильно возвращению из метода «1» (в широком смысле – любого положительного числа); + - `«<»` – возврат отрицательного числа (опять же, обычно – «-1»); + - `«==»` равносильно 0 (нулю). +2. `Comparable` – интерфейс, который должен быть имплементирован классом, объекты которого мы планируем сравнивать + (например, `String` имплементирует `Comparable`). `Comparator` – интерфейс, который расширяется конечными + реализациями _Comparator’а_ – отдельными классами-компараторами. Обычно эти классы реализуют в виде анонимным + классов (или лямбда-выражений, но с ними мы еще не знакомы); +3. `Comparable` подходит для простого сравнения, когда достаточно сравнить объекты одним конкретным способом (например, + строки всегда сравниваются в алфавитном порядке. Точнее, по номерам символов, из которых строки состоят). +4. `Comparator` подходит для ситуаций, когда объект нужно сравнивать по разным критериям в зависимости от ситуации. + Например, мы хотим иметь возможность отсортировать коллекцию сущностей _Человек_ по росту. А в другой ситуации – по + весу. Для каждой из этих ситуаций нам нужен отдельный компаратор; +5. В отличии от `Comparable`, `Comparator` поддерживает сложную сортировку. Используя метод `thenComparing()`* можно + реализовать сортировку коллекции по нескольким параметрам: скажем, сначала отсортировать коллекцию сущностей + _Человек_ по росту, а уже элементы с одинаковым ростом – по весу. Или наоборот. +6. Также `Comparator` содержит методы, позволяющие указать место `null`-объектов при сортировке (в начале или в + конце) – `nullsFirst()` и `nullsLast()` – и методы, определяющие порядок сортировки для Comparable-объектов (прямой + или обратный) – `reverseOrder()` и `naturalOrder()`. + +> *thenComparing() перегружен. На данном этапе нас интересует реализация с единственным параметром типа Comparator. + +На первый взгляд, наличие в Java и `Comparable`, и `Comparator` может показаться избыточным. Однако их сочетание и +грамотное использование может сильно упростить жизнь. Главное понимать, что зона ответственности `Comparable` – +непосредственно сравнение объектов (одним единственным верным в рамках логики программы образом), а зоной +ответственности `Comparator` являются сортировки (или определение порядка элементов в некоторых структурах данных). +Именно поэтому реализация `Comparable` для сущности может быть только одна, а реализаций `Comparator` – неограниченное +количество, включая совместное использование различных реализаций через `thenComparing()`. + +#### С теорией на сегодня все! + +![img.png](../../../commonmedia/defaultFooter.jpg) + +Переходим к практике: + +## Задача 1: + +Используя классы-сущности из +[задачи к уроку 21](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson21_immutable_object/model) +реализуйте сортировку машин по: + +- Номеру; +- Цвету; +- Году; +- Номеру и году. + +Используйте список для хранения и сортировки коллекции машин. + +## Задача 2: + +Используя классы-сущности из +[задачи к уроку 21](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson21_immutable_object/model) +имплементируйте `Comparable` для `Car` таким образом, чтобы машины сравнивались по полю `identifier`. +Объекты `CarIdentifier` предлагаю сравнивать по номеру и году (если номера почему-то совпали). + +Также реализуйте сортировку коллекции машин в прямом и обратном порядке. + +> Если что-то непонятно или не получается – welcome в комменты к посту или в лс:) +> +> Канал: https://t.me/ViamSupervadetVadens +> +> Мой тг: https://t.me/ironicMotherfucker +> +> **Дорогу осилит идущий!** \ No newline at end of file