J'essaie de trier la liste par ordre décroissant à l'aide de l'interface du comparateur. Mais les valeurs ne sont pas triées par ordre décroissant. Je ne sais pas ce que je fais mal ici.
public class Student {
int rollNo;
String name;
int age;
public Student(int RollNo, String Name, int Age){
this.rollNo = RollNo;
this.name = Name;
this.age = Age;
}
}
public class AgeComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Ascending
//return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Descending
}
}
public class Comparator_Sort {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Student> al = new ArrayList<Student>();
al.add(new Student(5978,"Vishnu", 50));
al.add(new Student(5979,"Vasanth", 30));
al.add(new Student(5980,"Santhosh", 40));
al.add(new Student(5981,"Santhosh", 20));
al.add(new Student(5982,"Santhosh", 10));
al.add(new Student(5983,"Santhosh", 5));
Collections.sort(al, new AgeComparator());
for(Student s : al){
System.out.println(s.rollNo+" "+s.name+" "+s.age);
}
}
}
Je peux être capable de trier la liste par ordre croissant, alors que je suis incapable de le faire par ordre décroissant
return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Sorted in Ascending
return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Not sorted in Descending
Documentation du comparateur - Résultats: un entier négatif, zéro ou un entier positif car le premier argument est inférieur, égal ou supérieur au second. La source se trouve depuis ici
Quelqu'un peut-il me dire pourquoi le tri par descente ne fonctionne pas?
Vos deux opérateurs conditionnels ternaires produisent le même résultat (puisque vous avez échangé >
avec <
et -1
avec 1
):
return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0); //Sorted in Ascending
return o1.age < o2.age ? -1 :(o1.age > o2.age ? 1 : 0); // Not sorted in Descending
Pour un ordre décroissant, vous avez besoin de:
return o1.age > o2.age ? -1 :(o1.age < o2.age ? 1 : 0);
@Eran a déjà signalé l'erreur dans votre comparateur.
J'aimerais ajouter que vous pouvez simplement renvoyer o1.age - o2.age
. Le résultat de la comparaison ne doit pas nécessairement être exactement -1
ou 1
pour <
ou >
; il peut simplement être négatif ou positif.
Et vous auriez aussi pu appeler Comparator.reversed
. Ou Comparator.comparing(Student::getAge).reversed()
.
Vous pouvez directement utiliser une instance de classe de comparateur. Voici l'exemple de code.
En supposant que vous définissiez une méthode getter "getAge()"
pour student.
Comparator<Student> m_studentComparator = new Comparator<Sudent>() {
@Override
public int compare(Student lhs, Student rhs) {
return rhs.getAge().compareTo(lhs.getAge()); // Descending order
}
};
Collections.sort(<<Your list>> , m_studentComparator); // this would return the descending order list.
Si vous souhaitez une liste d’ordre croissant, modifiez simplement l’instruction return de la méthode remplacée par
return lhs.getAge().compareTo(rjs.getAge()); // Ascending order.
J'espère que ça répond à ta question.
return o1.age > o2.age ? -1 :(o1.age < o2.age ? 1 : 0);
bien que pour décroissant, il vous suffit de multiplier votre déclaration de retour croissant par -1 comme ça
-1*(return o1.age > o2.age ? 1 :(o1.age < o2.age ? -1 : 0))
L'abus de conditions ternaires est sujet à erreur car illisible.
Pourquoi ne pas simplement écrire le if-else-if
classique pour le comparateur décroissant?
public class AgeComparatorDesc implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
if (o1.age > o2.age) {
return -1;
} else if (o1.age < o2.age) {
return 1;
}
return 0;
}
}
Eh bien, vous devriez soit l'écrire comme:
return o1.age < o2.age ? 1 :(o1.age > o2.age ? -1 : 0);
ou écrivez-le comme:
return o1.age > o2.age ? -1 :(o1.age < o2.age ? 1 : 0);
Votre tentative actuelle le triera toujours par ordre croissant.