У меня есть массив объектов person (int age; String name;)
.
Как я могу отсортировать этот массив по алфавиту по имени, а затем по возрасту?
Какой алгоритм вы бы использовали для этого?
Вы можете использовать Collections.sort
следующим образом:
private static void order(List<Person> persons) {
Collections.sort(persons, new Comparator() {
public int compare(Object o1, Object o2) {
String x1 = ((Person) o1).getName();
String x2 = ((Person) o2).getName();
int sComp = x1.compareTo(x2);
if (sComp != 0) {
return sComp;
}
Integer x1 = ((Person) o1).getAge();
Integer x2 = ((Person) o2).getAge();
return x1.compareTo(x2);
}});
}
List<Persons>
теперь сортируется по имени, затем по возрасту.
String.compareTo
«Сравнивает две строки лексикографически» - из документов .
Collections.sort
статический метод в родной библиотеке коллекций Он выполняет фактическую сортировку, вам просто нужно предоставить Comparator, который определяет, как должны сравниваться два элемента в вашем списке: это достигается путем обеспечения собственной реализации compare
метода.
Comparator
чтобы избежать приведения входных данных.Comparable
. Смотрите ответ @ berry120Comparator<Person> comparator = Comparator.comparing(Person::getName).thenComparingInt(Person::getAge);
Для тех, кто в состоянии использовать потоковый API Java 8, есть более аккуратный подход, который хорошо документирован здесь: лямбды и сортировка
Я искал эквивалент C # LINQ:
Я нашел механизм в Java 8 на Comparator:
Итак, вот фрагмент, который демонстрирует алгоритм.
Посмотрите приведенную выше ссылку для более точного подхода и объяснения того, как вывод типа Java делает его более неуклюжим по сравнению с LINQ.
Вот полный тестовый модуль для справки:
источник
Comparator<Person> comparator = Comparator.comparing(Person::getName).thenComparing(Person::getAge);
thenComparingInt
для возраста (int)Collections.sort(people, comparator);
вместо этого?Использование подхода Java 8 Streams ...
И Java 8 Lambda подход ...
И, наконец ...
источник
Вы должны реализовать свой собственный
Comparator
, а затем использовать его: например,Ваш компаратор может выглядеть примерно так:
Компаратор сначала сравнивает имена, если они не равны, он возвращает результат их сравнения, иначе он возвращает результат сравнения при сравнении возрастов обоих людей.
Этот код является всего лишь черновиком: поскольку класс является неизменяемым, вы можете подумать о создании его единственного элемента вместо создания нового экземпляра для каждой сортировки.
источник
Вы можете использовать Java 8 Lambda подход для достижения этой цели. Как это:
источник
Сделайте так, чтобы класс person реализовал,
Comparable<Person>
а затем внедрил метод CompareTo, например:Это будет сортировать сначала по имени (без учета регистра), а затем по возрасту. Вы можете запустить
Arrays.sort()
илиCollections.sort()
коллекцию или массив объектов Person.источник
Гуава
ComparisonChain
обеспечивает чистый способ сделать это. Ссылка на эту ссылку .Утилита для выполнения связанного оператора сравнения. Например:
источник
Вы можете сделать так:
источник
Используйте,
Comparator
а затем положить объекты вCollection
, тоCollections.sort();
источник
Создайте столько компараторов, сколько необходимо. После этого вызовите метод thenComparing для каждой категории заказа. Это способ сделать Streams. Видеть:
Посмотрите: Сортировать пользовательский объект по нескольким полям - Компаратор (лямбда-поток)
источник
Я был бы осторожен при использовании Guava,
ComparisonChain
потому что он создает экземпляр этого для каждого сравниваемого элемента, поэтому вы будете смотреть на созданиеN x Log N
цепочек сравнения просто для сравнения, если вы сортируете, илиN
экземпляров, если вы повторяете и проверяете на равенство.Вместо этого я бы создал статический файл
Comparator
с использованием новейшего API-интерфейса Java 8, если это возможно, илиOrdering
API-интерфейса Guava, который позволяет вам это делать, вот пример с Java 8:Вот как использовать
Ordering
API Guava : https://github.com/google/guava/wiki/OrderingExplainedисточник
compare
методу ничего не создает, но возвращает один из одноэлементных экземпляровLESS
,GREATER
или вACTIVE
зависимости от результата сравнения. Это высокооптимизированный подход, не требующий увеличения памяти или производительности.Или вы можете использовать тот факт, что
Collections.sort()
(илиArrays.sort()
) является стабильным (он не меняет порядок элементов, которые равны) и использовать сначалаComparator
сортировку по возрасту, а затем другую сортировку по имени.В данном конкретном случае это не очень хорошая идея, но если вам нужно изменить порядок сортировки во время выполнения, это может быть полезно.
источник
Вы можете использовать универсальный последовательный компаратор для сортировки коллекций по нескольким полям.
источник
Обновленная версия:
источник
Для такого класса
Book
:сортировка основного класса с помощью фиктивных объектов
источник
Я не уверен, что в этом случае писать урок внутри класса Person - это некрасиво. Сделал это так:
источник