Trier une collection d’objects

Si j’ai une liste simple de chaînes:

List ssortingngList = new ArrayList(); 

Je peux le sortinger avec:

 Collections.sort(ssortingngList); 

Mais supposons que j’ai une classe de personne:

 public class Person { private Ssortingng name; private Integer age; private Ssortingng country; } 

Et une liste de celui-ci:

 List personList = new ArrayList(); 

Et je veux parfois sortinger par nom, parfois par âge, parfois par pays.

Quel est le moyen le plus simple d’y parvenir?

Je sais que je peux implémenter l’interface Comparable, mais cela semble me limiter à la sortinger par une propriété spécifique.

Implémentez l’interface Comparator (une fois pour chaque ordre de sorting différent) et utilisez la méthode Collections.sort () qui prend un comparateur comme paramètre supplémentaire.

Collections.sort peut être appelé avec un comparateur personnalisé. Et ce comparateur peut être implémenté pour permettre un sorting dans différents ordres de sorting. Voici un exemple (pour votre modèle Personne – avec l’âge en tant qu’Integer):

 public class FlexiblePersonComparator implements Comparator { 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; } } 

Et vous l’utilisez comme ça (en supposant que les personnes soient un champ):

 public void sortPersonsBy(FlexiblePersonComparator.Order sortingBy) { List 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 } 

Merci aux intervenants. Pour le bénéfice des autres, j’aimerais inclure un exemple complet.

La solution est la création des classes supplémentaires suivantes:

 public class NameComparator implements Comparator { public int compare(Person o1, Person o2) { return o1.getName().compareTo(o2.getName()); } } public class AgeComparator implements Comparator { public int compare(Person o1, Person o2) { return o1.getAge().compareTo(o2.getAge()); } } public class CountryComparator implements Comparator { public int compare(Person o1, Person o2) { return o1.getCountry().compareTo(o2.getCountry()); } } 

La liste peut alors être sortingée comme ceci:

 Collections.sort(personList, new NameComparator()); Collections.sort(personList, new AgeComparator()); Collections.sort(personList, new CountryComparator()); 

La méthode Java 8 consiste à utiliser List.sort comme suit:

 personList.sort(Comparator.comparing(Person::getName)); 

Pour citer Stuart Marks dans sa réponse ici .

C’est le gros avantage de la méthode d’extension List.sort(cmp) sur Collections.sort(list, cmp) . Il peut sembler que ce soit simplement un petit avantage syntaxique pouvant écrire myList.sort(cmp) au lieu de Collections.sort(myList, cmp) . La différence est que myList.sort(cmp) , étant une méthode d’extension d’interface, peut être remplacée par l’implémentation de List spécifique. Par exemple, ArrayList.sort(cmp) sortinge la liste sur place à l’aide d’ Arrays.sort() tandis que l’implémentation par défaut implémente l’ancienne technique copyout-sort-copyback.

Vous pouvez également utiliser le BeanComparator à partir de beanutils apache commons, comme ceci:

 Collections.sort(personList, new BeanComparator("name")); 

Implémentez 3 types de comparateurs différents.

vous pouvez append le comparateur à la commande de sorting. Le comparateur que vous définissez va sortinger les éléments par nom, âge ou autre.

 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(); } }); 

La méthode Collections.sort peut être appelée avec un deuxième argument qui est le comparateur à utiliser. Créez 3 comparateurs et utilisez celui que vous souhaitez lorsque cela est approprié.

 Collections.sort(list , new Comparator() { public int compare(Object o1, Object o2) { ... } }); 

J’ai posé une question très similaire (à propos de la recherche plutôt que du sorting), il y a peut-être des informations utiles (j’ai fini par utiliser un enum qui implémente Comparator donc je passe la valeur enum tant que sélecteur de comparateur).

En utilisant lambdaj ( http://code.google.com/p/lambdaj/ ), vous pouvez réaliser ce que vous demandez de la manière suivante:

sort (personList, on (Person.class) .getName ());

sort (personList, on (Person.class) .getAge ());

sort (personList, on (Person.class) .getCountry ());