Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre Comparateur : Comparaison Personnalisée des Données | Fondamentaux et Capacités Fonctionnelles de l'API Stream
API Stream

bookComparateur : Comparaison Personnalisée des Données

Examinons la deuxième interface fonctionnelle, Comparator, voyons comment elle réalise la comparaison et comprenons la différence entre Comparator et Comparable.

Qu'est-ce que Comparator ?

La méthode clé de l'interface fonctionnelle Comparator est :

int compare(T o1, T o2);

La méthode compare(T o1, T o2) retourne :

  • Un nombre négatif si o1 est inférieur à o2 ;
  • Zéro si o1 et o2 sont égaux ;
  • Un nombre positif si o1 est supérieur à o2.

Application pratique

Mise en œuvre du tri d'objets Book à l'aide de l'interface Comparator. Au lieu d'implémenter la méthode de comparaison dans la classe Book elle-même, utilisation des méthodes statiques de l'interface Comparator pour définir la logique de tri.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
package com.example; import java.util.List; import java.util.ArrayList; import java.util.Comparator; public class Main { public static void main(String[] args) { List<Book> books = new ArrayList<>(); books.add(new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925)); books.add(new Book("To Kill a Mockingbird", "Harper Lee", 1960)); books.add(new Book("1984", "George Orwell", 1949)); // Sort by title books.sort(Comparator.comparing(Book::getTitle)); System.out.println("Sorted by title: " + books); System.out.println("------------------------"); // Sort by author books.sort(Comparator.comparing(Book::getAuthor)); System.out.println("Sorted by author: " + books); } } class Book { private String title; private String author; private int year; public Book(String title, String author, int year) { this.title = title; this.author = author; this.year = year; } public String getTitle() { return title; } public String getAuthor() { return author; } public int getYear() { return year; } @Override public String toString() { return title + " by " + author + " (" + year + ")"; } }

Dans cet exemple, l'interface Comparator est utilisée pour trier la liste books. Mais pourquoi utiliser la méthode comparing() au lieu de compare() ?

Pour utiliser la méthode compare(), il est nécessaire de créer un objet Comparator et d'implémenter la méthode compare.

public static Comparator<Book> titleComparator = new Comparator<Book>() {
    @Override
    public int compare(Book b1, Book b2) {
        return b1.getTitle().compareTo(b2.getTitle());
    }
};

Ce code définit un Comparator<Book> à l'aide d'une classe anonyme pour comparer deux objets Book selon leur title.

Puisque String implémente Comparable, la méthode compareTo() est utilisée pour comparer les titres lexicographiquement, renvoyant une valeur négative, zéro ou positive.

Il est également possible d'obtenir le même résultat avec une expression lambda pour une implémentation plus concise :

(b1, b2) -> b1.getTitle().compareTo(b2.getTitle());

Mais il existe une approche encore plus simple : utiliser la méthode Comparator.comparing(). Cette méthode gère automatiquement la logique de comparaison, ce qui la rend plus lisible et concise.

Il suffit de transmettre une référence de méthode qui extrait le champ à comparer.

Comparator.comparing(Book::getTitle)

La méthode sort() de la liste appelle le Comparator transmis, qui, à son tour, détermine l’ordre des éléments en les comparant selon les valeurs retournées par les méthodes spécifiées.

Tri multiple

Pour effectuer un tri selon plusieurs critères, il est possible d'utiliser la méthode thenComparing :

books.sort(
       Comparator.comparing(Book::getYear) // First by year
           .thenComparing(Book::getTitle) // Then by title
);

Cet exemple illustre comment trier une liste de livres d'abord par leur year de parution, puis par leur title. Le processus de tri compare d'abord les livres selon leur year ; si deux livres ont la même year, ils sont ensuite comparés par leur title pour déterminer leur ordre final.

Tri inversé

Inverser l'ordre de tri en Java est utile lorsqu'il est nécessaire de trier des éléments selon un critère puis de modifier l'ordre pour le critère suivant.

Les méthodes reversed() et Comparator.reverseOrder() permettent de contrôler la direction du tri, mais leur fonctionnement diffère.

books.sort(
    Comparator.comparing(Book::getYear).reversed() // Sort by year (descending)
        .thenComparing(Book::getTitle, Comparator.reverseOrder()) // Then by title (descending)
);

Les livres sont d'abord triés par leur année de parution en ordre décroissant à l'aide de reversed(). Si plusieurs livres partagent la même year, thenComparing() les trie par title en ordre alphabétique inversé grâce à Comparator.reverseOrder().

Cela garantit que les livres les plus récents apparaissent en premier et, au sein de la même année, les titres sont classés de Z à A.

Différences entre Comparable et Comparator

Utiliser l'interface Comparable lorsqu'une classe possède un ordre naturel, comme le tri par un champ unique. Utiliser Comparator pour trier selon plusieurs critères ou lorsqu'il est nécessaire de définir un ordre personnalisé pour les objets.

1. Quand utiliser l’interface Comparable ?

2. Quand utiliser l’interface Comparator ?

question mark

Quand utiliser l’interface Comparable ?

Select the correct answer

question mark

Quand utiliser l’interface Comparator ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 1. Chapitre 9

Demandez à l'IA

expand

Demandez à l'IA

ChatGPT

Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion

Awesome!

Completion rate improved to 2.33

bookComparateur : Comparaison Personnalisée des Données

Glissez pour afficher le menu

Examinons la deuxième interface fonctionnelle, Comparator, voyons comment elle réalise la comparaison et comprenons la différence entre Comparator et Comparable.

Qu'est-ce que Comparator ?

La méthode clé de l'interface fonctionnelle Comparator est :

int compare(T o1, T o2);

La méthode compare(T o1, T o2) retourne :

  • Un nombre négatif si o1 est inférieur à o2 ;
  • Zéro si o1 et o2 sont égaux ;
  • Un nombre positif si o1 est supérieur à o2.

Application pratique

Mise en œuvre du tri d'objets Book à l'aide de l'interface Comparator. Au lieu d'implémenter la méthode de comparaison dans la classe Book elle-même, utilisation des méthodes statiques de l'interface Comparator pour définir la logique de tri.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
package com.example; import java.util.List; import java.util.ArrayList; import java.util.Comparator; public class Main { public static void main(String[] args) { List<Book> books = new ArrayList<>(); books.add(new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925)); books.add(new Book("To Kill a Mockingbird", "Harper Lee", 1960)); books.add(new Book("1984", "George Orwell", 1949)); // Sort by title books.sort(Comparator.comparing(Book::getTitle)); System.out.println("Sorted by title: " + books); System.out.println("------------------------"); // Sort by author books.sort(Comparator.comparing(Book::getAuthor)); System.out.println("Sorted by author: " + books); } } class Book { private String title; private String author; private int year; public Book(String title, String author, int year) { this.title = title; this.author = author; this.year = year; } public String getTitle() { return title; } public String getAuthor() { return author; } public int getYear() { return year; } @Override public String toString() { return title + " by " + author + " (" + year + ")"; } }

Dans cet exemple, l'interface Comparator est utilisée pour trier la liste books. Mais pourquoi utiliser la méthode comparing() au lieu de compare() ?

Pour utiliser la méthode compare(), il est nécessaire de créer un objet Comparator et d'implémenter la méthode compare.

public static Comparator<Book> titleComparator = new Comparator<Book>() {
    @Override
    public int compare(Book b1, Book b2) {
        return b1.getTitle().compareTo(b2.getTitle());
    }
};

Ce code définit un Comparator<Book> à l'aide d'une classe anonyme pour comparer deux objets Book selon leur title.

Puisque String implémente Comparable, la méthode compareTo() est utilisée pour comparer les titres lexicographiquement, renvoyant une valeur négative, zéro ou positive.

Il est également possible d'obtenir le même résultat avec une expression lambda pour une implémentation plus concise :

(b1, b2) -> b1.getTitle().compareTo(b2.getTitle());

Mais il existe une approche encore plus simple : utiliser la méthode Comparator.comparing(). Cette méthode gère automatiquement la logique de comparaison, ce qui la rend plus lisible et concise.

Il suffit de transmettre une référence de méthode qui extrait le champ à comparer.

Comparator.comparing(Book::getTitle)

La méthode sort() de la liste appelle le Comparator transmis, qui, à son tour, détermine l’ordre des éléments en les comparant selon les valeurs retournées par les méthodes spécifiées.

Tri multiple

Pour effectuer un tri selon plusieurs critères, il est possible d'utiliser la méthode thenComparing :

books.sort(
       Comparator.comparing(Book::getYear) // First by year
           .thenComparing(Book::getTitle) // Then by title
);

Cet exemple illustre comment trier une liste de livres d'abord par leur year de parution, puis par leur title. Le processus de tri compare d'abord les livres selon leur year ; si deux livres ont la même year, ils sont ensuite comparés par leur title pour déterminer leur ordre final.

Tri inversé

Inverser l'ordre de tri en Java est utile lorsqu'il est nécessaire de trier des éléments selon un critère puis de modifier l'ordre pour le critère suivant.

Les méthodes reversed() et Comparator.reverseOrder() permettent de contrôler la direction du tri, mais leur fonctionnement diffère.

books.sort(
    Comparator.comparing(Book::getYear).reversed() // Sort by year (descending)
        .thenComparing(Book::getTitle, Comparator.reverseOrder()) // Then by title (descending)
);

Les livres sont d'abord triés par leur année de parution en ordre décroissant à l'aide de reversed(). Si plusieurs livres partagent la même year, thenComparing() les trie par title en ordre alphabétique inversé grâce à Comparator.reverseOrder().

Cela garantit que les livres les plus récents apparaissent en premier et, au sein de la même année, les titres sont classés de Z à A.

Différences entre Comparable et Comparator

Utiliser l'interface Comparable lorsqu'une classe possède un ordre naturel, comme le tri par un champ unique. Utiliser Comparator pour trier selon plusieurs critères ou lorsqu'il est nécessaire de définir un ordre personnalisé pour les objets.

1. Quand utiliser l’interface Comparable ?

2. Quand utiliser l’interface Comparator ?

question mark

Quand utiliser l’interface Comparable ?

Select the correct answer

question mark

Quand utiliser l’interface Comparator ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 1. Chapitre 9
some-alt