Java - Как использовать Comparator?

Привет, будущие маги Java! ? Сегодня мы отправимся в увлекательное путешествие в мир Java Comparators. Не волнуйтесь, если вы новички в программировании – я буду вашим доброжелательным гидом, и мы будем двигаться шаг за шагом. К концу этого учебника вы сможете сортировать объекты, как профи!

Java - Comparators

Что такое Comparator?

Прежде чем мы углубимся, представьте, что вы организовываете свою книжную полку. Вы можете захотеть arranging ваши книги по названию, автору или дате публикации. В Java, Comparator resembles вашего личного библиотекаря, который знает, как отсортировать вашу коллекцию в зависимости от любого критерия, который вы выберете.

На техническом языке, Comparator - это интерфейс в Java, который позволяет нам определять пользовательский порядок для объектов. Он особенно полезен, когда мы хотим сортировать объекты, которые не имеют естественного порядка, или когда мы хотим сортировать их по-другому, чем их естественный порядок.

Интерфейс Comparator

Давайте closer look на интерфейс Comparator:

public interface Comparator<T> {
int compare(T o1, T o2);
}

Не пугайтесь! Это проще, чем кажется. <T> просто говорит, что этот интерфейс может работать с любым типом объекта. Метод compare - это место, где происходит магия - это как если бы вы просили вашего библиотекаря сравнить две книги.

Как работает метод compare

Метод compare принимает два объекта и возвращает целое число:

  • Если первый объект считается "меньше" второго, он возвращает отрицательное число.
  • Если они считаются "равными", он возвращает ноль.
  • Если первый "больше" второго, он возвращает положительное число.

Представьте это как весы. Если первый объект легче, весы отклоняются в отрицательную сторону. Если они равны, весы остаются сбалансированными на нуле. Если первый тяжелее, весы отклоняются в положительную сторону.

Создание вашего первого Comparator

Давайте создадим простой Comparator для сортировки строк по их длине. Мы назовем его StringLengthComparator:

import java.util.Comparator;

public class StringLengthComparator implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}

Вот что происходит:

  1. Мы импортируем интерфейс Comparator из java.util.
  2. Мы создаем класс, который реализует Comparator<String>, то есть он будет сравнивать строковые объекты.
  3. Мы перегружаем метод compare, чтобы вычесть длину второго файла из первого.

Использование вашего Comparator

Теперь, когда у нас есть наш Comparator, давайте использует его! Мы создадим список строк и отсортируем его:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparatorExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Pear");
fruits.add("Banana");
fruits.add("Kiwi");

System.out.println("Before sorting: " + fruits);

Collections.sort(fruits, new StringLengthComparator());

System.out.println("After sorting: " + fruits);
}
}

Вывод:

Before sorting: [Apple, Pear, Banana, Kiwi]
After sorting: [Pear, Kiwi, Apple, Banana]

Давайте разберем это:

  1. Мы создаем список названий фруктов.
  2. Мы打印аем исходный список.
  3. Мы используем Collections.sort() с нашим пользовательским Comparator для сортировки списка.
  4. Мы打印аем отсортированный список.

Обратите внимание, как фрукты теперь отсортированы по длине их названий!

Лямбда-выражения:shortcut

Java 8 ввела лямбда-выражения, которые могут сделать наш Comparator еще более кратким. Вот та же самая запись с использованием лямбды:

Collections.sort(fruits, (s1, s2) -> s1.length() - s2.length());

Эта一行ер делает exactly то же самое, что и наш класс StringLengthComparator! Это как если бы вы говорили Java: "Когда вы сравниваете две строки, просто вычтите их длины."

Сортировка пользовательских объектов

Теперь давайте поднимем планку и отсортируем некоторые пользовательские объекты. Представьте, что у нас есть класс Person:

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 + ")";
}
}

Мы можем создать Comparator для сортировки объектов Person по возрасту:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class PersonSortExample {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 30));
people.add(new Person("Charlie", 22));

System.out.println("Before sorting: " + people);

Collections.sort(people, Comparator.comparingInt(Person::getAge));

System.out.println("After sorting: " + people);
}
}

Вывод:

Before sorting: [Alice (25), Bob (30), Charlie (22)]
After sorting: [Charlie (22), Alice (25), Bob (30)]

Здесь мы используем Comparator.comparingInt(), который создает Comparator на основе целого числа - в данном случае, возраста. Person::getAge - это метод референция, указывающая Java использовать метод getAge() для получения значения для сравнения.

Изменение порядка сортировки

Что, если мы хотим отсортировать в порядке убывания? Легко! Просто используйте метод reversed():

Collections.sort(people, Comparator.comparingInt(Person::getAge).reversed());

Это отсортирует наши объекты Person от старших к младшим.

_chain Comparators

Иногда мы можем захотеть отсортировать по нескольким критериям. Например, давайте отсортируем объекты Person по возрасту, а если возраста одинаковые, то по имени:

Comparator<Person> ageAndNameComparator = Comparator
.comparingInt(Person::getAge)
.thenComparing(Person::getName);

Collections.sort(people, ageAndNameComparator);

Это создает Comparator, который сначала compares возраста, а если они равны, compares имена.

Заключение

Поздравляю! Вы только что узнали все тонкости Java Comparators. От сортировки простых строк до сложных объектов, вы теперь можете организовывать данные любым способом, который вы выберете. Помните, что практика makes perfect, поэтому не бойтесь экспериментировать с различными критериями сортировки и объектами.

Пока вы продолжаете свое путешествие в Java, вы найдете Comparators бесценными инструментами в вашем наборе программирования. Они не только для сортировки списков - они используются во многих Java коллекциях и алгоритмах для поддержания порядка и выполнения эффективных поисков.

Продолжайте программировать, продолжайте учиться и, самое главное, получайте удовольствие! Кто знает? Может быть,有一天 вы напишете сортировочный алгоритм, который изменит способ, которым мы организуем данные. Пока что, счастливого сравнивания! ??‍??‍?

Methods of Comparator Interface

Вот таблица ключевых методов в интерфейсе Comparator:

Метод Описание
compare(T o1, T o2) Сравнивает свои два аргумента по порядку.
equals(Object obj) Indicates whether some other object is "equal to" this comparator.
reversed() Возвращает comparator, который устанавливает обратный порядок этого comparator.
thenComparing(Comparator<? super T> other) Возвращает лексикографический comparator с другим comparator.
thenComparingInt(ToIntFunction<? super T> keyExtractor) Возвращает лексикографический comparator с функцией, которая извлекает целое число sort ключ.
thenComparingLong(ToLongFunction<? super T> keyExtractor) Возвращает лексикографический comparator с функцией, которая извлекает long sort ключ.
thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) Возвращает лексикографический comparator с функцией, которая извлекает double sort ключ.

Эти методы предоставляют мощные инструменты для создания сложной сортировочной логики, позволяя вам создавать сложные comparators для любого типа данных или сортировочного требования.

Credits: Image by storyset