Інтерфейси Comparable та Comporator. Сортування
В Java інтерфейси Comparable і Comparator використовуються для сортування об’єктів у колекціях. Вони забезпечують механізм для порівняння об’єктів і дозволяють впорядковувати їх у певному порядку.
1. Інтерфейс Comparable
Інтерфейс Comparable використовується, коли клас визначає природний порядок сортування об’єктів. Клас, який реалізує Comparable, повинен перевизначити метод compareTo(), який визначає, як об’єкти цього класу будуть порівнюватися між собою.
Метод compareTo:
int compareTo(T o): Повертає:
- негативне число, якщо поточний об’єкт менший за об’єкт `o`;
- нуль, якщо об’єкти рівні;
- позитивне число, якщо поточний об’єкт більший за `o`.
Приклад використання Comparable:
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Реалізація методу compareTo для сортування за віком
@Override
public int compareTo(Person other) {
return Integer.compare(this.age, other.age);
}
@Override
public String toString() {
return name + ” (” + age + “)”;
}
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person(“Іван”, 30));
people.add(new Person(“Анна”, 25));
people.add(new Person(“Петро”, 35));
// Сортування за природним порядком (за віком)
Collections.sort(people);
System.out.println(people); // Виведе [Анна (25), Іван (30), Петро (35)]
}
}
У цьому прикладі клас Person реалізує інтерфейс Comparable і сортує людей за віком. Метод compareTo визначає, як буде відбуватися порівняння між об’єктами цього класу.
2. Інтерфейс Comparator
Інтерфейс Comparator використовується для сортування об’єктів за неприродним порядком, або коли потрібно сортувати об’єкти за кількома критеріями. На відміну від Comparable, Comparator не змінює клас, який потрібно сортувати, а створює окремий об’єкт для порівняння.
Основні методи Comparator:
int compare(T o1, T o2): Порівнює два об’єкти `o1` та `o2`, повертаючи:
- негативне число, якщо `o1` менший за `o2`;
- нуль, якщо `o1` і `o2` рівні;
- позитивне число, якщо `o1` більший за `o2`.
static Comparator<T> comparing(Function<T, U> keyExtractor): Створює компаратор на основі функції для вибору ключа для порівняння.
Приклад використання `Comparator` для кількох критеріїв сортування:
import java.util.*;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + ” (” + age + “)”;
}
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person(“Іван”, 30));
people.add(new Person(“Анна”, 25));
people.add(new Person(“Петро”, 30));
// Сортування за ім’ям
Comparator<Person> nameComparator = Comparator.comparing(person -> person.name);
Collections.sort(people, nameComparator);
System.out.println(“Сортування за ім’ям: ” + people);
// Сортування за віком, потім за ім’ям
Comparator<Person> ageThenNameComparator = Comparator.comparing((Person p) -> p.age)
.thenComparing(p -> p.name);
Collections.sort(people, ageThenNameComparator);
System.out.println(“Сортування за віком, потім за ім’ям: ” + people);
}
}
Пояснення:
- У першому випадку ми сортуємо людей за іменем за допомогою методу `comparing`.
- У другому випадку ми спочатку сортуємо за віком, а якщо вік однаковий, то сортуємо за іменем. Метод `thenComparing` дозволяє додавати кілька рівнів сортування.
3. Сортування у Java
Java надає методи для сортування колекцій та масивів:
- Collections.sort(List<T> list): сортує список за природним порядком, якщо елементи реалізують інтерфейс `Comparable`.
- Collections.sort(List<T> list, Comparator<? super T> c): сортує список за вказаним компаратором.
- Arrays.sort(Object[] array): сортує масив за природним порядком.
- Arrays.sort(Object[] array, Comparator<? super T> c): сортує масив за вказаним компаратором.
Приклад сортування з компаратором:
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> cities = new ArrayList<>();
cities.add(“Київ”);
cities.add(“Львів”);
cities.add(“Одеса”);
// Сортування в алфавітному порядку
Collections.sort(cities);
System.out.println(“Алфавітне сортування: ” + cities);
// Сортування у зворотному алфавітному порядку
Collections.sort(cities, Comparator.reverseOrder());
System.out.println(“Зворотнє сортування: ” + cities);
}
}
4. Сортування з лямбда-виразами
В Java 8 були додані лямбда-вирази, що спрощують синтаксис для створення анонімних компараторів. З їх допомогою можна легко створювати компаратори на льоту.
Приклад сортування з використанням лямбда-виразів:
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person(“Іван”, 30));
people.add(new Person(“Анна”, 25));
people.add(new Person(“Петро”, 35));
// Сортування за віком з використанням лямбда-виразу
people.sort((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()));
System.out.println(“Сортування за віком: ” + people);
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return name + ” (” + age + “)”;
}
}
Висновок
- Comparable використовується для встановлення природного порядку сортування у класі, реалізуючи метод `compareTo()`.
- Comparator надає можливість визначати альтернативні стратегії сортування, дозволяючи сортувати за кількома критеріями або змінювати порядок на льоту
- Обидва інтерфейси є важливими для реалізації сортування об’єктів у Java та можуть бути використані для вирішення різноманітних завдань у програмуванні.