Сортировка коллекции объектов [дубликат]
этот вопрос уже есть ответ здесь:
- Сортировка ArrayList объектов с помощью пользовательского порядка сортировки 9 ответов
если у меня есть простой список строк:
List<String> stringList = new ArrayList<String>();
Я могу сортировать его:
Collections.sort(stringList);
но предположим, что у меня есть класс Person:
public class Person
{
private String name;
private Integer age;
private String country;
}
и список это:
List<Person> personList = new ArrayList<Person>();
и я хочу сортировать его иногда по имени, иногда по возрасту, иногда по стране.
какой самый простой способ добиться этого?
Я знаю, что могу реализовать сопоставимый интерфейс, но это, кажется, ограничивает меня сортировать его по одному конкретному свойству.
9 ответов:
реализовать компаратор интерфейс (один раз для каждого другого порядка сортировки) и использовать сборники.сортировка () метод, который принимает компаратор в качестве дополнительного параметра.
сборники.сортировка может быть вызвана с помощью пользовательского компаратора. И этот компаратор может быть реализован, чтобы разрешить сортировку в разных порядках сортировки. Вот пример (для вашей модели лица - с возрастом в виде целого числа):
public class FlexiblePersonComparator implements Comparator<Person> { public enum Order {Name, Age, Country} private Order sortingBy = Name; @Override public int compare(Person person1, Person person2) { switch(sortingBy) { case Name: return person1.name.compareTo(person2.name); case Age: return person1.age.compareTo(person2.age); case Country: return person1.country.compareTo(person2.country); } throw new RuntimeException("Practically unreachable code, can't be thrown"); } public void setSortingBy(Order sortBy) { this.sortingBy = sortingBy; } }
и вы используете его так (предполагая, что persons-это поле):
public void sortPersonsBy(FlexiblePersonComparator.Order sortingBy) { List<Person> persons = this.persons; // useless line, just for clarification FlexiblePersonComparator comparator = new FlexiblePersonComparator(); comparator.setSortingBy(sortingBy); Collections.sort(persons, comparator); // now we have a sorted list }
спасибо ответчикам. Для пользы других, я хотел бы включить полный пример.
решение заключается в создании следующих дополнительных классов:
public class NameComparator implements Comparator<Person> { public int compare(Person o1, Person o2) { return o1.getName().compareTo(o2.getName()); } } public class AgeComparator implements Comparator<Person> { public int compare(Person o1, Person o2) { return o1.getAge().compareTo(o2.getAge()); } } public class CountryComparator implements Comparator<Person> { public int compare(Person o1, Person o2) { return o1.getCountry().compareTo(o2.getCountry()); } }
список может быть отсортирован следующим образом:
Collections.sort(personList, new NameComparator()); Collections.sort(personList, new AgeComparator()); Collections.sort(personList, new CountryComparator());
Java 8 способ сделать это-использовать
List.sort
следующим образом:personList.sort(Comparator.comparing(Person::getName));
цитата Стюарт Марки в ответ здесь.
это большое преимущество
List.sort(cmp)
метод расширения надCollections.sort(list, cmp)
. Может показаться, что это всего лишь небольшое синтаксическое преимущество-возможность писатьmyList.sort(cmp)
вместоCollections.sort(myList, cmp)
. Разница в том, чтоmyList.sort(cmp)
, будучи методом расширения интерфейса, можно переопределить конкретныеList
реализация. Например,ArrayList.sort(cmp)
сортирует список на месте с помощьюArrays.sort()
в то время как реализация по умолчанию реализует старый метод copyout-sort-copyback.
вы также можете использовать BeanComparator из apache commons beanutils, например:
Collections.sort(personList, new BeanComparator("name"));
реализовать 3 различных типа компаратора.
вы можете добавить компаратор в команду сортировки. Компаратор, который вы определяете, будет сортировать элементы по имени, возрасту или чему-либо еще.
Collections.sort(list, new Comparator() { public int compare(Object arg0, Object arg1) { if (!(arg0 instanceof Person)) { return -1; } if (!(arg1 instanceof Person)) { return -1; } Person pers0 = (Person)arg0; Person pers1 = (Person)arg1; // COMPARE NOW WHAT YOU WANT // Thanks to Steve Kuo for your comment! return pers0.getAge() - pers1.getAge(); } });
Коллекций.метод сортировки может быть вызван со вторым аргументом, который является компаратором для использования. Создайте 3 компаратора и используйте тот, который вы хотите, когда это необходимо.
Collections.sort(list , new Comparator() { public int compare(Object o1, Object o2) { ... } });
попросил очень похожий вопрос (о поиске, а не сортировке), возможно, есть какая-то полезная информация (я закончил с помощью
enum
что реализуетComparator
поэтому я передаюenum
значение в качестве селектора-компаратора).
используя lambdaj ( http://code.google.com/p/lambdaj/) Вы можете достичь того, что вы просите следующим образом:
сортировать (personList, on (Person.класс.)getName ());
сортировать (personList, on (Person.класс.)getAge());
сортировать (personList, on (Person.класс.)getCountry());