Je veux trier mes objets par ordre décroissant en utilisant un comparateur.
class Person {
private int age;
}
Ici, je veux trier un tableau d'objets Personne.
Comment puis-je le faire ?
Je veux trier mes objets par ordre décroissant en utilisant un comparateur.
class Person {
private int age;
}
Ici, je veux trier un tableau d'objets Personne.
Comment puis-je le faire ?
Vous pouvez effectuer le tri descendant d'une classe définie par l'utilisateur de cette manière en surchargeant la fonction comparer() méthode,
Collections.sort(unsortedList,new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return b.getName().compareTo(a.getName());
}
});
Ou en utilisant Collection.reverse()
pour trier en ordre décroissant comme utilisateur Prince mentionné dans son commentaire .
Et vous pouvez faire le tri ascendant comme ceci,
Collections.sort(unsortedList,new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
});
Remplacez le code ci-dessus par une expression Lambda (à partir de Java 8) et vous obtiendrez un code concis :
Collections.sort(personList, (Person a, Person b) -> b.getName().compareTo(a.getName()));
À partir de Java 8, List a trier() qui prend Comparateur comme paramètre (plus concis) :
personList.sort((a,b)->b.getName().compareTo(a.getName()));
Ici a
y b
sont déduits comme type de personne par l'expression lambda.
Pour ce que ça vaut, voici ma réponse standard. La seule chose nouvelle ici est qu'elle utilise la fonction Collections.reverseOrder(). De plus, toutes les suggestions sont regroupées dans un seul exemple :
/*
** Use the Collections API to sort a List for you.
**
** When your class has a "natural" sort order you can implement
** the Comparable interface.
**
** You can use an alternate sort order when you implement
** a Comparator for your class.
*/
import java.util.*;
public class Person implements Comparable<Person>
{
String name;
int age;
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name + " : " + age;
}
/*
** Implement the natural order for this class
*/
public int compareTo(Person p)
{
return getName().compareTo(p.getName());
}
static class AgeComparator implements Comparator<Person>
{
public int compare(Person p1, Person p2)
{
int age1 = p1.getAge();
int age2 = p2.getAge();
if (age1 == age2)
return 0;
else if (age1 > age2)
return 1;
else
return -1;
}
}
public static void main(String[] args)
{
List<Person> people = new ArrayList<Person>();
people.add( new Person("Homer", 38) );
people.add( new Person("Marge", 35) );
people.add( new Person("Bart", 15) );
people.add( new Person("Lisa", 13) );
// Sort by natural order
Collections.sort(people);
System.out.println("Sort by Natural order");
System.out.println("\t" + people);
// Sort by reverse natural order
Collections.sort(people, Collections.reverseOrder());
System.out.println("Sort by reverse natural order");
System.out.println("\t" + people);
// Use a Comparator to sort by age
Collections.sort(people, new Person.AgeComparator());
System.out.println("Sort using Age Comparator");
System.out.println("\t" + people);
// Use a Comparator to sort by descending age
Collections.sort(people,
Collections.reverseOrder(new Person.AgeComparator()));
System.out.println("Sort using Reverse Age Comparator");
System.out.println("\t" + people);
}
}
Je voudrais créer un comparateur pour la classe de personne qui peut être paramétré avec un certain comportement de tri. Ici, je peux définir l'ordre de tri, mais il peut être modifié pour permettre le tri d'autres attributs de la personne.
public class PersonComparator implements Comparator<Person> {
public enum SortOrder {ASCENDING, DESCENDING}
private SortOrder sortOrder;
public PersonComparator(SortOrder sortOrder) {
this.sortOrder = sortOrder;
}
@Override
public int compare(Person person1, Person person2) {
Integer age1 = person1.getAge();
Integer age2 = person2.getAge();
int compare = Math.signum(age1.compareTo(age2));
if (sortOrder == ASCENDING) {
return compare;
} else {
return compare * (-1);
}
}
}
(j'espère que ça compile maintenant, je n'ai pas d'IDE ou de JDK sous la main, j'ai codé 'à l'aveugle')
Modifier
Merci à Thomas, j'ai modifié le code. Je ne dirais pas que l'utilisation de Math.signum est bonne, performante, efficace, mais j'aimerais le garder pour rappeler que la méthode compareTo peut retourner n'importe quel entier et que la multiplication par (-1) échouera si l'implémentation retourne Integer.MIN_INTEGER... Et j'ai supprimé le setter parce que c'est assez bon marché de construire un nouveau PersonComparator juste quand c'est nécessaire.
Mais je garde la boîte parce que cela montre que je m'appuie sur une implémentation existante de Comparable. On aurait pu faire quelque chose comme Comparable<Integer> age1 = new Integer(person1.getAge());
mais ça avait l'air trop moche. L'idée était de montrer un modèle qui pourrait facilement être adapté à d'autres attributs de la personne, comme le nom, l'anniversaire en tant que date, etc.
String[] s = {"a", "x", "y"};
Arrays.sort(s, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
System.out.println(Arrays.toString(s));
-> [y, x, a]
Maintenant, vous devez implémenter le Comparateur pour votre classe Personne. Quelque chose comme (pour un ordre croissant) : compare(Person a, Person b) = a.id < b.id ? -1 : (a.id == b.id) ? 0 : 1
o Integer.valueOf(a.id).compareTo(Integer.valueOf(b.id))
.
Pour minimiser la confusion, vous devriez implémenter un comparateur ascendant et le convertir en un comparateur descendant avec un wrapper ( comme ceci ) new ReverseComparator<Person>(new PersonComparator())
.
Utilisation de Google Collections :
class Person {
private int age;
public static Function<Person, Integer> GET_AGE =
new Function<Person, Integer> {
public Integer apply(Person p) { return p.age; }
};
}
public static void main(String[] args) {
ArrayList<Person> people;
// Populate the list...
Collections.sort(people, Ordering.natural().onResultOf(Person.GET_AGE).reverse());
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.