Java: Trier une ArrayList suivant les attributs d'un objet

Exemple avec l'objet personnalisé suivant

class Personne {
    
    String Nom;
    String Prenom;
    int Age;
    char Sexe;
    
    public Personne(String Nom, String Prenom, int Age, char Sexe) {
        this.Nom = Nom;
        this.Prenom = Prenom;
        this.Age = Age;
        this.Sexe = Sexe;
    }
    
    public boolean equals(Object o) {
        if (o instanceof Personne) {
            Personne tocompare = (Personne) o;
            if (tocompare.Nom.equals(this.Nom) && tocompare.Prenom.equals(this.Prenom)) {
                return true;
            }
        }
        return false;
    }
    
    public String toString(){
        return String.format("Nom: %-15sPrénom: %-15sAge: %-4dSexe: %1s", this.Nom, this.Prenom, this.Age, this.Sexe);
    }

    public String getNom() {
        return Nom;
    }

    public void setNom(String nom) {
        Nom = nom;
    }

    public String getPrenom() {
        return Prenom;
    }

    public void setPrenom(String prenom) {
        Prenom = prenom;
    }

    public int getAge() {
        return Age;
    }

    public void setAge(int age) {
        Age = age;
    }

    public char getSexe() {
        return Sexe;
    }

    public void setSexe(char sexe) {
        Sexe = sexe;
    }

}

Je vais maintenant créer 10 objets "Personne" et les ajouter dans une ArrayList.

import java.util.ArrayList;

public class TriPersoPersonne {

    public static void main(String[] args) {
        ArrayList<Personne> Personnes = new ArrayList<Personne>();
        Personnes.add(new Personne("Martine", "Merle", 38, 'F'));
        Personnes.add(new Personne("Martine", "Boutin", 22, 'M'));
        Personnes.add(new Personne("Claire", "Lombard", 28, 'M'));
        Personnes.add(new Personne("Eugène", "Faivre", 53, 'F'));
        Personnes.add(new Personne("Susanne", "Gérard", 91, 'F'));
        Personnes.add(new Personne("Zoé", "Lefebvre", 47, 'F'));
        Personnes.add(new Personne("Julien", "Ollivier", 86, 'M'));
        Personnes.add(new Personne("Thomas", "Lambert", 38, 'M'));
        Personnes.add(new Personne("Michel", "Gay", 69, 'M'));
        Personnes.add(new Personne("Bernadette", "Clément", 15, 'F'));
        for (Personne personne : Personnes) {
            System.out.println(personne);
        }
    }

}

Voici la sortie du System.out:

Nom: Martine        Prénom: Merle          Age: 38  Sexe: F
Nom: Martine        Prénom: Boutin         Age: 22  Sexe: M
Nom: Claire         Prénom: Lombard        Age: 28  Sexe: M
Nom: Eugène         Prénom: Faivre         Age: 53  Sexe: F
Nom: Susanne        Prénom: Gérard         Age: 91  Sexe: F
Nom: Zoé            Prénom: Lefebvre       Age: 47  Sexe: F
Nom: Julien         Prénom: Ollivier       Age: 86  Sexe: M
Nom: Thomas         Prénom: Lambert        Age: 38  Sexe: M
Nom: Michel         Prénom: Gay            Age: 69  Sexe: M
Nom: Bernadette     Prénom: Clément        Age: 15  Sexe: F

J'aimerais maintenant trier mon ArrayList en fonction de l'age et du sexe de la personne et mettre la priorité sur le sexe "F" en cas d'égalité de l'age.

import java.util.Comparator;

class TriParAgeEtSexe implements Comparator<Personne> {
    
    public int compare(Personne a, Personne b) {
        int compA = a.Age * 10 + sexeToInt(a.Sexe);
        int compB = b.Age * 10 + sexeToInt(b.Sexe);
        return compA - compB;
    }
    
    public static int sexeToInt(char sexe) {
        if (sexe == 'F') return 0;
        return 1;
    }
    
}

Exécutons maintenant le tri de l'ArrayList avec mon tri personnalisé.

import java.util.ArrayList;
import java.util.Collections;

public class TriPersoPersonne {

    public static void main(String[] args) {
        ArrayList<Personne> Personnes = new ArrayList<Personne>();
        Personnes.add(new Personne("Martine", "Merle", 38, 'F'));
        Personnes.add(new Personne("Martine", "Boutin", 22, 'M'));
        Personnes.add(new Personne("Claire", "Lombard", 28, 'M'));
        Personnes.add(new Personne("Eugène", "Faivre", 53, 'F'));
        Personnes.add(new Personne("Susanne", "Gérard", 91, 'F'));
        Personnes.add(new Personne("Zoé", "Lefebvre", 47, 'F'));
        Personnes.add(new Personne("Julien", "Ollivier", 86, 'M'));
        Personnes.add(new Personne("Thomas", "Lambert", 38, 'M'));
        Personnes.add(new Personne("Michel", "Gay", 69, 'M'));
        Personnes.add(new Personne("Bernadette", "Clément", 15, 'F'));
        for (Personne personne : Personnes) {
            System.out.println(personne);
        }
        System.out.println("\nAprès le tri par age et sexe\n");
        Collections.sort(Personnes, new TriParAgeEtSexe());
        for (Personne personne : Personnes) {
            System.out.println(personne);
        }
    }

}

Ce qui donne ceci:

Nom: Martine        Prénom: Merle          Age: 38  Sexe: F
Nom: Martine        Prénom: Boutin         Age: 22  Sexe: M
Nom: Claire         Prénom: Lombard        Age: 28  Sexe: M
Nom: Eugène         Prénom: Faivre         Age: 53  Sexe: F
Nom: Susanne        Prénom: Gérard         Age: 91  Sexe: F
Nom: Zoé            Prénom: Lefebvre       Age: 47  Sexe: F
Nom: Julien         Prénom: Ollivier       Age: 86  Sexe: M
Nom: Thomas         Prénom: Lambert        Age: 38  Sexe: M
Nom: Michel         Prénom: Gay            Age: 69  Sexe: M
Nom: Bernadette     Prénom: Clément        Age: 15  Sexe: F

Après le tri par age et sexe

Nom: Bernadette     Prénom: Clément        Age: 15  Sexe: F
Nom: Martine        Prénom: Boutin         Age: 22  Sexe: M
Nom: Claire         Prénom: Lombard        Age: 28  Sexe: M
Nom: Martine        Prénom: Merle          Age: 38  Sexe: F
Nom: Thomas         Prénom: Lambert        Age: 38  Sexe: M
Nom: Zoé            Prénom: Lefebvre       Age: 47  Sexe: F
Nom: Eugène         Prénom: Faivre         Age: 53  Sexe: F
Nom: Michel         Prénom: Gay            Age: 69  Sexe: M
Nom: Julien         Prénom: Ollivier       Age: 86  Sexe: M
Nom: Susanne        Prénom: Gérard         Age: 91  Sexe: F

Le résultat est parfait.
L'ArrayList est triée par age croissant et si égalité, alors le sexe "F"  est positionné avant le sexe "M".

Et pour un tri décroissant, il suffit de modifier le "return" de la méthode "compare" de la classe "TriParAgeEtSexe" par:

return compB - compA;

Pour info, la méthode "equals" de la classe "Personne" permet d'utiliser la méthode "contains" de la classe "ArrayList" afin de vérifier si un objet "Personne" n'est pas déjà dans la liste avant de l'ajouter afin d'éviter les doublons.