У меня есть класс Person
с несколькими свойствами, например:
public class Person {
private int id;
private String name, address;
// Many more properties.
}
Многие Person
объекты -объекты хранятся в файле ArrayList<Person>
. Я хочу отсортировать этот список по нескольким параметрам сортировки, время от времени меняющимся. Например, один раз я мог бы захотеть отсортировать по name
возрастанию, а затем по address
убыванию, а в другой раз просто по id
убыванию.
И я не хочу создавать свои собственные методы сортировки (т. Е. Я хочу использовать Collections.sort(personList, someComparator)
. Какое наиболее элегантное решение, позволяющее добиться этого?)
comparator.reversed()
нисходящиеcomparator1.thenComparing(comparator2)
компараторы и связывать их.Вы можете создать компараторы для каждого свойства, которое вы, возможно, захотите отсортировать, а затем попробовать «объединение в цепочку компараторов» :-) вот так:
источник
Один из способов - создать объект,
Comparator
который принимает в качестве аргументов список свойств для сортировки, как показано в этом примере.Затем его можно использовать в коде, например, так:
источник
Один из подходов - составить
Comparator
s. Это может быть библиотечный метод (я уверен, что он где-то существует).Использование:
В качестве альтернативы обратите внимание, что
Collections.sort
это стабильная сортировка. Если производительность не имеет решающего значения, вы занимаетесь второстепенным порядком, а не основным.источник
compose(nameComparator, compose(addressComparator, idComparator))
Было бы лучше, если бы в Java были методы расширения.Компараторы позволяют сделать это очень легко и естественно. Вы можете создавать отдельные экземпляры компараторов либо в самом классе Person, либо в классе Service, связанном с вашими потребностями.
Примеры с использованием анонимных внутренних классов:
Если у вас их много, вы также можете структурировать код компараторов так, как вам нравится. Например, вы можете:
источник
Я думаю, что объединение сортировщиков с классом Person, как в вашем ответе, не является хорошей идеей, потому что оно связывает сравнение (обычно бизнес-ориентированное) и объект модели, чтобы они приблизились друг к другу. Каждый раз, когда вы хотите изменить / добавить что-то в сортировщике, вам нужно прикоснуться к классу людей, чего вы обычно не хотите делать.
Использование службы или чего-то подобного, которое предоставляет экземпляры Comparator, такие как предложенный KLE, звучит более гибко и расширяемо.
источник
Мой подход основан на подходе Ишая. Основной пробел в том, что нет способа отсортировать сначала по возрастанию для атрибута, а затем по убыванию для другого. Этого нельзя сделать с помощью перечислений. Для этого я использовал классы. Поскольку SortOrder сильно зависит от типа, я предпочел реализовать его как внутренний класс человека.
Класс Person с внутренним классом SortOrder:
Пример использования класса Person и его SortOrder:
oRUMOo
источник
Недавно я написал компаратор для сортировки нескольких полей в строковой записи с разделителями. Он позволяет вам определять разделитель, структуру записи и правила сортировки (некоторые из которых зависят от типа). Вы можете использовать это, преобразовав запись Person в строку с разделителями.
Необходимая информация передается в сам компаратор программно или через XML-файл.
XML проверяется встроенным файлом XSD пакета. Например, ниже представлен макет записи с разделителями табуляцией и четырьмя полями (два из которых можно сортировать):
Затем вы могли бы использовать это в java следующим образом:
Библиотеку можно найти здесь:
http://sourceforge.net/projects/multicolumnrowcomparator/
источник
Предположим, существует класс
Coordinate
и нужно отсортировать его обоими способами по координате X и координате Y. Для этого необходимы два разных компаратора. Ниже образецисточник