web-dev-qa-db-fra.com

java - Tri par ordre décroissant à l'aide d'un comparateur

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?

6
Aishu

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);
9
Eran

@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().

5
lexicore

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.

1
Akhil Ghatiki
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))
0
skY

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

}
0
davidxxx

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.

0
user3437460