Exemple de tri d’objets Java (Comparable et Comparator)

Exemple de tri d'objets Java (Comparable et Comparator)

Dans ce didacticiel, il montre l'utilisation dejava.lang.Comparable etjava.util.Comparator pour trier un objet Java en fonction de sa valeur de propriété.

1. Trier un tableau

Pour trier un tableau, utilisez lesArrays.sort().

    String[] fruits = new String[] {"Pineapple","Apple", "Orange", "Banana"};

    Arrays.sort(fruits);

    int i=0;
    for(String temp: fruits){
        System.out.println("fruits " + ++i + " : " + temp);
    }

Sortie

fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple

2. Trier une liste de tableaux

Pour trier une ArrayList, utilisez lesCollections.sort().

    List fruits = new ArrayList();

    fruits.add("Pineapple");
    fruits.add("Apple");
    fruits.add("Orange");
    fruits.add("Banana");

    Collections.sort(fruits);

    int i=0;
    for(String temp: fruits){
        System.out.println("fruits " + ++i + " : " + temp);
    }

Sortie

fruits 1 : Apple
fruits 2 : Banana
fruits 3 : Orange
fruits 4 : Pineapple

3. Trier un objet avec comparable

Que diriez-vous d'un objet Java? Créons une classe Fruit:

public class Fruit{

    private String fruitName;
    private String fruitDesc;
    private int quantity;

    public Fruit(String fruitName, String fruitDesc, int quantity) {
        super();
        this.fruitName = fruitName;
        this.fruitDesc = fruitDesc;
        this.quantity = quantity;
    }

    public String getFruitName() {
        return fruitName;
    }
    public void setFruitName(String fruitName) {
        this.fruitName = fruitName;
    }
    public String getFruitDesc() {
        return fruitDesc;
    }
    public void setFruitDesc(String fruitDesc) {
        this.fruitDesc = fruitDesc;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
}

Pour le trier, vous pouvez penser à nouveau àArrays.sort(), voir l'exemple ci-dessous:

package com.example.common.action;

import java.util.Arrays;

public class SortFruitObject{

    public static void main(String args[]){

        Fruit[] fruits = new Fruit[4];

        Fruit pineappale = new Fruit("Pineapple", "Pineapple description",70);
        Fruit apple = new Fruit("Apple", "Apple description",100);
        Fruit orange = new Fruit("Orange", "Orange description",80);
        Fruit banana = new Fruit("Banana", "Banana description",90);

        fruits[0]=pineappale;
        fruits[1]=apple;
        fruits[2]=orange;
        fruits[3]=banana;

        Arrays.sort(fruits);

        int i=0;
        for(Fruit temp: fruits){
           System.out.println("fruits " + ++i + " : " + temp.getFruitName() +
            ", Quantity : " + temp.getQuantity());
        }

    }
}

Bien essayé, mais qu'est-ce que vous attendez desArrays.sort()? Vous n'avez même pas mentionné quoi trier dans la classe Fruit. Ainsi, il rencontrera l'erreur suivante:

Exception in thread "main" java.lang.ClassCastException:
com.example.common.Fruit cannot be cast to java.lang.Comparable
    at java.util.Arrays.mergeSort(Unknown Source)
    at java.util.Arrays.sort(Unknown Source)

Pour trier un objet par sa propriété, vous devez faire en sorte que l'objet implémente l'interfaceComparable et écrase la méthodecompareTo(). Voyons à nouveau la nouvelle classe Fruit.

public class Fruit implements Comparable{

    private String fruitName;
    private String fruitDesc;
    private int quantity;

    public Fruit(String fruitName, String fruitDesc, int quantity) {
        super();
        this.fruitName = fruitName;
        this.fruitDesc = fruitDesc;
        this.quantity = quantity;
    }

    public String getFruitName() {
        return fruitName;
    }
    public void setFruitName(String fruitName) {
        this.fruitName = fruitName;
    }
    public String getFruitDesc() {
        return fruitDesc;
    }
    public void setFruitDesc(String fruitDesc) {
        this.fruitDesc = fruitDesc;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public int compareTo(Fruit compareFruit) {

        int compareQuantity = ((Fruit) compareFruit).getQuantity();

        //ascending order
        return this.quantity - compareQuantity;

        //descending order
        //return compareQuantity - this.quantity;

    }
}

La nouvelle classe Fruit a implémenté l'interfaceComparable et a remplacé la méthodecompareTo() pour comparer sa propriété de quantité dans l'ordre croissant.

La méthodecompareTo() est difficile à expliquer, dans le tri d'entiers, rappelez-vous simplement

  1. this.quantity – compareQuantity is ascending order.

  2. compareQuantity - this.quantity est un ordre décroissant.

Pour en savoir plus sur la méthode compareTo (), lisez ceciComparable documentation.

Exécutez-le à nouveau, maintenant le tableau Fruits est trié par sa quantité dans l'ordre croissant.

fruits 1 : Pineapple, Quantity : 70
fruits 2 : Orange, Quantity : 80
fruits 3 : Banana, Quantity : 90
fruits 4 : Apple, Quantity : 100

4. Trier un objet avec un comparateur

Que diriez-vous de trier avec «fruitName» ou «quantité» de Fruit? L'interface comparable n'est autorisée qu'à trier une seule propriété. Pour trier avec plusieurs propriétés, vous avez besoin deComparator. Voir à nouveau la nouvelle classe Fruit mise à jour:

import java.util.Comparator;

public class Fruit implements Comparable{

    private String fruitName;
    private String fruitDesc;
    private int quantity;

    public Fruit(String fruitName, String fruitDesc, int quantity) {
        super();
        this.fruitName = fruitName;
        this.fruitDesc = fruitDesc;
        this.quantity = quantity;
    }

    public String getFruitName() {
        return fruitName;
    }
    public void setFruitName(String fruitName) {
        this.fruitName = fruitName;
    }
    public String getFruitDesc() {
        return fruitDesc;
    }
    public void setFruitDesc(String fruitDesc) {
        this.fruitDesc = fruitDesc;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public int compareTo(Fruit compareFruit) {

        int compareQuantity = ((Fruit) compareFruit).getQuantity();

        //ascending order
        return this.quantity - compareQuantity;

        //descending order
        //return compareQuantity - this.quantity;

    }

    public static Comparator FruitNameComparator
                          = new Comparator() {

        public int compare(Fruit fruit1, Fruit fruit2) {

          String fruitName1 = fruit1.getFruitName().toUpperCase();
          String fruitName2 = fruit2.getFruitName().toUpperCase();

          //ascending order
          return fruitName1.compareTo(fruitName2);

          //descending order
          //return fruitName2.compareTo(fruitName1);
        }

    };
}

La classe Fruit contient une méthode statiqueFruitNameComparator pour comparer le «fruitName». Désormais, l'objet Fruit est capable de trier avec la propriété "quantité" ou "fruitName". Exécutez-le à nouveau.

1. Trier le tableau Fruit en fonction de sa propriété «fruitName» dans l'ordre croissant.

Arrays.sort(fruits, Fruit.FruitNameComparator);

Sortie

fruits 1 : Apple, Quantity : 100
fruits 2 : Banana, Quantity : 90
fruits 3 : Orange, Quantity : 80
fruits 4 : Pineapple, Quantity : 70

2. Trier le tableau Fruit en fonction de sa propriété «quantité» dans l'ordre croissant.

Arrays.sort(fruits)

Sortie

fruits 1 : Pineapple, Quantity : 70
fruits 2 : Orange, Quantity : 80
fruits 3 : Banana, Quantity : 90
fruits 4 : Apple, Quantity : 100

Lesjava.lang.Comparable etjava.util.Comparator sont puissants mais prennent du temps à comprendre et à s'en servir, peut-être est-ce dû au manque d'exemple de détail.

Mes pensées…

À l'avenir, la classe Arrays devrait fournir une méthode plus générique et plus pratique -Arrays.sort(Object, String, flag).

Pour trier un tableau d'objets par son «fruitName» dans l'ordre croissant.

Arrays.sort(fruits, fruitName, Arrays.ASCENDING);

Pour trier un tableau d'objets par sa «quantité» dans l'ordre croissant.

Arrays.sort(fruits, quantity, Arrays.DESCENDING);