Сортировка массива объектов по двум полям в Java
Быстрый ответ
Для эффективной сортировки списка в Java по двум свойствам можно использовать сочетание методов Comparator.comparing
и thenComparing
.
List<Person> people = // ... инициализация списка
people.sort(
Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
);
В этом примере список people
сортируется сначала по атрибуту lastName
(фамилия), затем — по firstName
(имя), используя ссылки на методы.
Пошаговое руководство по сортировке для начинающих
Властелин сортировки: Comparator
Чтобы отсортировать объекты по нескольким параметрам, вы можете создать собственный Comparator
. Он позволяет сравнивать строки и числа с использованием метода compareTo
.
// Поле для гольфа готово, отсортируем игроков по фамилии и возрасту!
Comparator<Person> peopleSorter = Comparator
.comparing(Person::getLastName)
.thenComparingInt(Person::getAge);
// Посмотрим, кто лучше играет.
Collections.sort(people, peopleSorter);
Java 8 и Streams: идеальное сочетание
В Java 8 API для потоков предусматривает возможность сортировки по двум полям.
// Гольферы, приветствуйте сортировку ваших данных по возрасту и фамилии!
List<Person> sortedPeople = people.stream()
.sorted(Comparator.comparing(Person::getAge)
.thenComparing(Person::getLastName))
.collect(Collectors.toList());
Регистрозависимость: важно ли это?
Для сортировки строк без учета регистра используйте String.compareToIgnoreCase()
.
Comparator<Person> caseInsensitiveComparator = Comparator
.comparing(Person::getName, String.CASE_INSENSITIVE_ORDER)
.thenComparingInt(Person::getAge);
// Независимо от того, как написаны имена — "Джон" или "джон"...
Collections.sort(people, caseInsensitiveComparator);
Для повторяющихся задач: реализация Comparable
Если вам часто приходится сортировать объекты Person
по двум параметрам, стоит реализовать интерфейс Comparable
.
public class Person implements Comparable<Person> {
// поля, конструкторы, геттеры
@Override
public int compareTo(Person other) {
int lastNameComparison = this.lastName.compareTo(other.lastName);
return lastNameComparison != 0 ? lastNameComparison : Integer.compare(this.age, other.age);
// Если фамилии одинаковые, сортируем по возрасту.
}
}
// Gandalf, ваши "подчиненные" готовы к работе...
Collections.sort(people); // вмешательство compareTo.
Визуализация
Допустим, нам нужно отсортировать колоду карт сначала по номиналу карты, затем по масти:
Исходная колода: [♠2, ♥3, ♠3, ♥2, ♣2]
Итог двухэтапной сортировки:
Шаг 1:Сортировка по номиналу Шаг 2: Сортировка по масти
[♠2, ♥2, ♣2, ♥3, ♠3] -> [♣2, ♥2, ♠2, ♥3, ♠3] // Масти отсортированы в соответствии с их кодами в Unicode.
Когда важна деталь: пользовательский Comparator
Если требуется особая сортировка для объекта Person
, можно создать пользовательский компаратор:
Comparator<Person> customComparator = new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
// Здесь может быть ваша своя логика сравнения.
}
};
Collections.sort(people, customComparator); // Сортировка выполнена, приятного чаепития!
Производительность превыше всего: один Comparator для всего
Создайте единичный экземпляр Comparator
для экономии ресурсов и улучшения повторного использования:
// Для тех, кто ценит производительность: общий Comparator в действии.
public class PersonComparators {
public static final Comparator<Person> BY_NAME_AND_AGE = Comparator
.comparing(Person::getName)
.thenComparingInt(Person::getAge);
// Закрытый конструктор для предотвращения создания экземпляров класса.
private PersonComparators() {}
}
Collections.sort(people, PersonComparators.BY_NAME_AND_AGE); // Сортируем быстро и эффективно.
Золотое правило: Доверяй, но проверяй
Для эффективной сортировки лучше всего использовать встроенные инструменты Java, такие как Collections.sort
и Comparator
.
Полезные материалы
- Comparator (Java Platform SE 8) — официальная документация Oracle по
Comparator
в Java. - Java – How to Use Comparator? — практическое руководство по работе с
Comparator
. - Java 8 Stream sorted() Example — примеры сортировки потоков в Java 8 и их объяснения.
- Effective Java – Joshua Bloch – Google Книги — подробный анализ важности реализации
Comparable
. - Java – How to Use Comparator? — продвинутое руководство по созданию пользовательских компараторов.