Introduction
Comparer des objets Java en fonction de plusieurs attributs est une compétence essentielle pour tout développeur Java. Cette capacité permet un tri, un filtrage et une organisation efficaces des données dans les applications. Dans ce lab, vous apprendrez à implémenter différents mécanismes de comparaison en Java pour gérer des objets avec plusieurs propriétés.
Nous explorerons les approches fondamentales pour comparer des objets en Java, notamment la surcharge de la méthode equals(), l'implémentation de l'interface Comparable et l'utilisation de l'interface Comparator. Grâce à des exemples pratiques et des exercices pratiques, vous acquerrez une solide compréhension de quand et comment utiliser chaque approche.
Création d'une classe Étudiant avec plusieurs attributs
Dans cette première étape, nous allons créer une classe Java simple pour représenter un étudiant avec plusieurs attributs. Cela servira de base pour l'apprentissage de la comparaison d'objets en Java.
Configuration de la structure du projet
Commençons par créer un répertoire pour notre projet et y naviguer :
mkdir -p ~/project/java-comparison
cd ~/project/java-comparison
Création de la classe Étudiant
Maintenant, créons une classe Student avec plusieurs attributs tels que le nom, l'âge et la note. Ouvrez le WebIDE et créez un nouveau fichier nommé Student.java dans le répertoire du projet avec le contenu suivant :
public class Student {
private String name;
private int age;
private double grade;
// Constructor
public Student(String name, int age, double grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
// Getters
public String getName() {
return name;
}
public int getAge() {
return age;
}
public double getGrade() {
return grade;
}
// toString method for easy display
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + ", grade=" + grade + "}";
}
}
Cette classe représente un étudiant avec trois attributs : name (une chaîne de caractères), age (un entier) et grade (un double). Nous avons également inclus un constructeur, des getters pour chaque attribut et une méthode toString() pour faciliter l'affichage des informations sur l'étudiant.
Test de la classe Étudiant
Créons une classe principale pour tester notre classe Student. Créez un nouveau fichier nommé StudentTest.java avec le contenu suivant :
public class StudentTest {
public static void main(String[] args) {
// Create some student objects
Student alice = new Student("Alice", 20, 85.5);
Student bob = new Student("Bob", 22, 90.0);
Student charlie = new Student("Charlie", 19, 78.3);
// Display student information
System.out.println("Student 1: " + alice);
System.out.println("Student 2: " + bob);
System.out.println("Student 3: " + charlie);
// Compare two students using == (identity comparison)
Student aliceCopy = alice;
System.out.println("\nIdentity comparison (==):");
System.out.println("alice == bob: " + (alice == bob));
System.out.println("alice == aliceCopy: " + (alice == aliceCopy));
// Try to compare students with built-in methods
System.out.println("\nNote: At this point, we cannot properly compare students based on their attributes.");
System.out.println("We will implement proper comparison in the next steps.");
}
}
Compilation et exécution
Maintenant, compilons et exécutons notre code :
javac StudentTest.java
java StudentTest
Vous devriez voir une sortie similaire à celle-ci :
Student 1: Student{name='Alice', age=20, grade=85.5}
Student 2: Student{name='Bob', age=22, grade=90.0}
Student 3: Student{name='Charlie', age=19, grade=78.3}
Identity comparison (==):
alice == bob: false
alice == aliceCopy: true
Note: At this point, we cannot properly compare students based on their attributes.
We will implement proper comparison in the next steps.
Comprendre les bases de la comparaison d'objets
Remarquez dans notre test que nous avons utilisé l'opérateur == pour comparer deux objets Student. C'est ce qu'on appelle la comparaison d'identité en Java, qui vérifie si deux références pointent vers le même objet en mémoire.
Cependant, nous avons souvent besoin de comparer des objets en fonction de leur contenu ou de leurs attributs, ce qu'on appelle la comparaison d'égalité. Java fournit plusieurs mécanismes à cet effet :
- Surcharge de la méthode
equals() - Implémentation de l'interface
Comparable - Utilisation de l'interface
Comparator
Dans les prochaines étapes, nous implémenterons ces mécanismes pour comparer les objets Student en fonction de leurs attributs.
Implémentation des méthodes equals() et hashCode()
Avant de plonger dans les interfaces Comparable et Comparator, implémentons d'abord les méthodes equals() et hashCode() dans notre classe Student. Ces méthodes sont fondamentales pour une comparaison d'objets correcte en Java.
Comprendre equals() et hashCode()
En Java, la méthode equals() est utilisée pour vérifier si deux objets sont égaux en fonction de leur contenu, tandis que la méthode hashCode() génère une valeur numérique qui représente l'objet. Ces deux méthodes fonctionnent ensemble, en particulier lorsque les objets sont stockés dans des collections comme HashMap ou HashSet.
Une implémentation correcte doit suivre ces règles :
- Si deux objets sont égaux selon
equals(), ils doivent avoir le même code de hachage. - Si deux objets ont le même code de hachage, ils ne sont pas nécessairement égaux.
Mise à jour de la classe Étudiant
Mettons à jour notre classe Student pour surcharger ces méthodes. Ouvrez Student.java et ajoutez les méthodes suivantes :
public class Student {
private String name;
private int age;
private double grade;
// Existing constructor and getters...
// Existing toString method...
// Override equals method
@Override
public boolean equals(Object obj) {
// Check if same object reference
if (this == obj) return true;
// Check if null or different class
if (obj == null || getClass() != obj.getClass()) return false;
// Cast to Student
Student other = (Student) obj;
// Compare attributes
return age == other.age &&
Double.compare(grade, other.grade) == 0 &&
(name == null ? other.name == null : name.equals(other.name));
}
// Override hashCode method
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
result = 31 * result + (int) (Double.doubleToLongBits(grade) ^ (Double.doubleToLongBits(grade) >>> 32));
return result;
}
}
La méthode equals() suit un modèle standard :
- Vérifier si l'objet est comparé à lui-même
- Vérifier si l'objet est nul ou d'une classe différente
- Convertir l'objet au type approprié
- Comparer chaque attribut pour l'égalité
La méthode hashCode() combine les codes de hachage de tous les attributs pour générer un code de hachage unique pour l'objet.
Test de equals() et hashCode()
Maintenant, mettons à jour notre fichier StudentTest.java pour tester ces méthodes :
public class StudentTest {
public static void main(String[] args) {
// Create some student objects
Student alice = new Student("Alice", 20, 85.5);
Student bob = new Student("Bob", 22, 90.0);
Student aliceDuplicate = new Student("Alice", 20, 85.5); // Same attributes as Alice
// Display student information
System.out.println("Student 1: " + alice);
System.out.println("Student 2: " + bob);
System.out.println("Student 3 (Alice duplicate): " + aliceDuplicate);
// Identity comparison (==)
System.out.println("\nIdentity comparison (==):");
System.out.println("alice == bob: " + (alice == bob));
System.out.println("alice == aliceDuplicate: " + (alice == aliceDuplicate));
// Equality comparison (equals())
System.out.println("\nEquality comparison (equals()):");
System.out.println("alice.equals(bob): " + alice.equals(bob));
System.out.println("alice.equals(aliceDuplicate): " + alice.equals(aliceDuplicate));
// Hash code comparison
System.out.println("\nHash code comparison:");
System.out.println("alice.hashCode(): " + alice.hashCode());
System.out.println("bob.hashCode(): " + bob.hashCode());
System.out.println("aliceDuplicate.hashCode(): " + aliceDuplicate.hashCode());
}
}
Compilation et exécution
Compilons et exécutons notre code mis à jour :
javac Student.java StudentTest.java
java StudentTest
La sortie devrait ressembler à ceci :
Student 1: Student{name='Alice', age=20, grade=85.5}
Student 2: Student{name='Bob', age=22, grade=90.0}
Student 3 (Alice duplicate): Student{name='Alice', age=20, grade=85.5}
Identity comparison (==):
alice == bob: false
alice == aliceDuplicate: false
Equality comparison (equals()):
alice.equals(bob): false
alice.equals(aliceDuplicate): true
Hash code comparison:
alice.hashCode(): 62509338
bob.hashCode(): 62565066
aliceDuplicate.hashCode(): 62509338
Remarquez que bien qu'alice et aliceDuplicate soient des objets différents (comme le montre la comparaison ==), ils sont considérés comme égaux selon notre méthode equals() car ils ont les mêmes valeurs d'attribut. De plus, ils ont le même code de hachage, comme l'exige le contrat entre equals() et hashCode().
Bien que equals() soit utile pour déterminer si deux objets sont égaux, il ne nous aide pas à établir un ordre entre les objets (comme lequel doit venir en premier dans une liste triée). Pour cela, nous avons besoin de l'interface Comparable, que nous implémenterons à l'étape suivante.
Implémentation de l'interface Comparable
La méthode equals() nous permet de vérifier si deux objets sont égaux, mais elle ne nous aide pas à établir un ordre. Pour cela, Java fournit l'interface Comparable, qui nous permet de définir un "ordre naturel" pour nos objets.
Comprendre l'interface Comparable
L'interface Comparable<T> possède une seule méthode, compareTo(T o), qui compare l'objet courant avec un autre objet du même type. La méthode renvoie :
- Un entier négatif si l'objet courant est inférieur à l'autre objet
- Zéro si l'objet courant est égal à l'autre objet
- Un entier positif si l'objet courant est supérieur à l'autre objet
En implémentant cette interface, nous pouvons définir comment les objets de notre classe doivent être ordonnés.
Mise à jour de la classe Étudiant
Mettons à jour notre classe Student pour implémenter l'interface Comparable. Nous allons définir l'ordre naturel en fonction de la note de l'étudiant (les notes les plus élevées en premier), puis par âge (les étudiants les plus jeunes en premier), et enfin par nom (ordre alphabétique).
Mettez à jour votre fichier Student.java :
public class Student implements Comparable<Student> {
private String name;
private int age;
private double grade;
// Existing constructor, getters, toString, equals, and hashCode methods...
// Implement compareTo method from Comparable interface
@Override
public int compareTo(Student other) {
// Compare by grade (descending order)
if (Double.compare(other.grade, this.grade) != 0) {
return Double.compare(other.grade, this.grade);
}
// If grades are equal, compare by age (ascending order)
if (this.age != other.age) {
return Integer.compare(this.age, other.age);
}
// If grades and ages are equal, compare by name (alphabetical order)
return this.name.compareTo(other.name);
}
}
Création d'un test pour l'implémentation de Comparable
Créons un nouveau fichier ComparableTest.java pour tester notre implémentation de Comparable :
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ComparableTest {
public static void main(String[] args) {
// Create a list of students
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 20, 85.5));
students.add(new Student("Bob", 22, 90.0));
students.add(new Student("Charlie", 19, 78.3));
students.add(new Student("David", 21, 85.5));
students.add(new Student("Eve", 20, 92.7));
// Display unsorted list
System.out.println("Unsorted list of students:");
for (Student student : students) {
System.out.println(student);
}
// Sort the list using the natural ordering defined by Comparable
Collections.sort(students);
// Display sorted list
System.out.println("\nSorted list of students (by grade descending, then age ascending, then name):");
for (Student student : students) {
System.out.println(student);
}
// Let's compare some students directly using compareTo
Student alice = students.get(3); // Alice should be at index 3 after sorting
Student bob = students.get(1); // Bob should be at index 1 after sorting
System.out.println("\nComparing students directly using compareTo:");
int comparison = alice.compareTo(bob);
System.out.println("alice.compareTo(bob) = " + comparison);
if (comparison < 0) {
System.out.println("Alice comes before Bob in the natural ordering");
} else if (comparison > 0) {
System.out.println("Bob comes before Alice in the natural ordering");
} else {
System.out.println("Alice and Bob are equal in the natural ordering");
}
}
}
Compilation et exécution
Compilons et exécutons notre code :
javac Student.java ComparableTest.java
java ComparableTest
La sortie devrait ressembler à ceci :
Unsorted list of students:
Student{name='Alice', age=20, grade=85.5}
Student{name='Bob', age=22, grade=90.0}
Student{name='Charlie', age=19, grade=78.3}
Student{name='David', age=21, grade=85.5}
Student{name='Eve', age=20, grade=92.7}
Sorted list of students (by grade descending, then age ascending, then name):
Student{name='Eve', age=20, grade=92.7}
Student{name='Bob', age=22, grade=90.0}
Student{name='Alice', age=20, grade=85.5}
Student{name='David', age=21, grade=85.5}
Student{name='Charlie', age=19, grade=78.3}
Comparing students directly using compareTo:
alice.compareTo(bob) = 1
Bob comes before Alice in the natural ordering
Remarquez que les étudiants sont maintenant triés par leur note par ordre décroissant. Lorsque les notes sont égales (comme pour Alice et David, tous deux avec 85,5), ils sont triés par âge par ordre croissant.
L'interface Comparable fournit un ordre naturel pour nos objets, mais que se passe-t-il si nous voulons trier les objets de différentes manières à différents moments ? Par exemple, nous pourrions parfois vouloir trier les étudiants par nom, et d'autres fois par âge. C'est là que l'interface Comparator entre en jeu, que nous explorerons à l'étape suivante.
Utilisation de Comparator pour un Ordre Personnalisé
L'interface Comparable fournit un ordre naturel pour notre classe, mais parfois nous avons besoin de trier les objets de différentes manières en fonction de différents critères. C'est là que l'interface Comparator s'avère utile.
Comprendre l'interface Comparator
L'interface Comparator<T> définit une méthode compare(T o1, T o2) qui compare deux objets du même type. Contrairement à Comparable, qui est implémentée par la classe en cours de comparaison, un Comparator est une classe séparée ou une expression lambda qui peut définir divers critères d'ordre.
Création de Comparateurs Personnalisés
Créons plusieurs comparateurs pour notre classe Student :
NameComparator: Trie les étudiants par nom (ordre alphabétique)AgeComparator: Trie les étudiants par âge (ordre croissant)GradeComparator: Trie les étudiants par note (ordre décroissant)
Créez un nouveau fichier appelé StudentComparators.java avec le contenu suivant :
import java.util.Comparator;
public class StudentComparators {
// Comparator for sorting students by name
public static class NameComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
return s1.getName().compareTo(s2.getName());
}
}
// Comparator for sorting students by age
public static class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
return Integer.compare(s1.getAge(), s2.getAge());
}
}
// Comparator for sorting students by grade (descending)
public static class GradeComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
return Double.compare(s2.getGrade(), s1.getGrade());
}
}
// Multi-attribute comparator: sort by grade (descending), then by name (alphabetically)
public static class GradeNameComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
// First compare by grade (descending)
int gradeComparison = Double.compare(s2.getGrade(), s1.getGrade());
if (gradeComparison != 0) {
return gradeComparison;
}
// If grades are equal, compare by name (alphabetically)
return s1.getName().compareTo(s2.getName());
}
}
}
Test des Comparateurs
Maintenant, créons une classe de test pour démontrer comment utiliser ces comparateurs. Créez un fichier nommé ComparatorTest.java :
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Comparator;
public class ComparatorTest {
public static void main(String[] args) {
// Create a list of students
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 20, 85.5));
students.add(new Student("Bob", 22, 90.0));
students.add(new Student("Charlie", 19, 78.3));
students.add(new Student("David", 21, 85.5));
students.add(new Student("Eve", 20, 92.7));
// Display original list
System.out.println("Original list of students:");
printStudents(students);
// Sort by name using NameComparator
Collections.sort(students, new StudentComparators.NameComparator());
System.out.println("\nStudents sorted by name:");
printStudents(students);
// Sort by age using AgeComparator
Collections.sort(students, new StudentComparators.AgeComparator());
System.out.println("\nStudents sorted by age (ascending):");
printStudents(students);
// Sort by grade using GradeComparator
Collections.sort(students, new StudentComparators.GradeComparator());
System.out.println("\nStudents sorted by grade (descending):");
printStudents(students);
// Sort by grade, then by name using GradeNameComparator
Collections.sort(students, new StudentComparators.GradeNameComparator());
System.out.println("\nStudents sorted by grade (descending), then by name:");
printStudents(students);
// Using Java 8 lambda expressions for comparators
System.out.println("\nUsing Java 8 lambda expressions:");
// Sort by name (alphabetically) using lambda
Collections.sort(students, (s1, s2) -> s1.getName().compareTo(s2.getName()));
System.out.println("\nStudents sorted by name (using lambda):");
printStudents(students);
// Sort by age (descending) using lambda
Collections.sort(students, (s1, s2) -> Integer.compare(s2.getAge(), s1.getAge()));
System.out.println("\nStudents sorted by age (descending, using lambda):");
printStudents(students);
// Using Comparator.comparing method
System.out.println("\nUsing Comparator.comparing method:");
// Sort by name
Collections.sort(students, Comparator.comparing(Student::getName));
System.out.println("\nStudents sorted by name (using Comparator.comparing):");
printStudents(students);
// Sort by grade (descending), then by age (ascending), then by name
Collections.sort(students,
Comparator.comparing(Student::getGrade, Comparator.reverseOrder())
.thenComparing(Student::getAge)
.thenComparing(Student::getName));
System.out.println("\nStudents sorted by grade (desc), then age (asc), then name:");
printStudents(students);
}
// Helper method to print the list of students
private static void printStudents(List<Student> students) {
for (Student student : students) {
System.out.println(student);
}
}
}
Compilation et exécution
Compilons et exécutons notre code :
javac Student.java StudentComparators.java ComparatorTest.java
java ComparatorTest
La sortie démontrera comment les différents comparateurs affectent l'ordre de tri des étudiants :
Original list of students:
Student{name='Alice', age=20, grade=85.5}
Student{name='Bob', age=22, grade=90.0}
Student{name='Charlie', age=19, grade=78.3}
Student{name='David', age=21, grade=85.5}
Student{name='Eve', age=20, grade=92.7}
Students sorted by name:
Student{name='Alice', age=20, grade=85.5}
Student{name='Bob', age=22, grade=90.0}
Student{name='Charlie', age=19, grade=78.3}
Student{name='David', age=21, grade=85.5}
Student{name='Eve', age=20, grade=92.7}
... (and so on for the other sorting methods)
Différences clés entre Comparable et Comparator
Il est important de comprendre les différences entre Comparable et Comparator :
Emplacement de l'implémentation :
Comparableest implémenté par la classe elle-même.Comparatorest implémenté dans une classe séparée ou sous forme d'expression lambda.
Nombre d'ordres :
Comparabledéfinit un seul "ordre naturel" pour une classe.Comparatorpermet plusieurs ordres différents.
Signatures de méthode :
Comparableaint compareTo(T o)Comparatoraint compare(T o1, T o2)
Utilisation :
Comparableest plus simple lorsqu'il existe un ordre naturel évident.Comparatorest plus flexible lorsque plusieurs ordres sont nécessaires.
Dans la dernière étape, nous allons créer une application concrète qui utilise à la fois Comparable et Comparator pour gérer une base de données d'étudiants.
Construction d'un Système de Gestion des Étudiants
Maintenant que nous comprenons comment comparer des objets en utilisant equals(), Comparable et Comparator, construisons un système simple de gestion des étudiants qui regroupe le tout dans une application pratique.
Création de la classe StudentManager
Créons une classe qui gérera une collection d'étudiants et fournira diverses opérations sur ceux-ci. Créez un fichier nommé StudentManager.java :
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
public class StudentManager {
private List<Student> students;
public StudentManager() {
students = new ArrayList<>();
}
// Add a student to the list
public void addStudent(Student student) {
students.add(student);
}
// Get all students
public List<Student> getAllStudents() {
return new ArrayList<>(students); // Return a copy to prevent modification
}
// Get top students by grade
public List<Student> getTopStudents(int count) {
List<Student> sortedStudents = new ArrayList<>(students);
Collections.sort(sortedStudents, new StudentComparators.GradeComparator());
// Return the top 'count' students or all if there are fewer
return sortedStudents.subList(0, Math.min(count, sortedStudents.size()));
}
// Get students sorted by name
public List<Student> getStudentsSortedByName() {
List<Student> sortedStudents = new ArrayList<>(students);
Collections.sort(sortedStudents, new StudentComparators.NameComparator());
return sortedStudents;
}
// Get students sorted by age
public List<Student> getStudentsSortedByAge() {
List<Student> sortedStudents = new ArrayList<>(students);
Collections.sort(sortedStudents, new StudentComparators.AgeComparator());
return sortedStudents;
}
// Get students with grade above threshold
public List<Student> getStudentsAboveGrade(double threshold) {
List<Student> result = new ArrayList<>();
for (Student student : students) {
if (student.getGrade() > threshold) {
result.add(student);
}
}
return result;
}
// Get students grouped by age
public Map<Integer, List<Student>> getStudentsGroupedByAge() {
Map<Integer, List<Student>> map = new HashMap<>();
for (Student student : students) {
int age = student.getAge();
if (!map.containsKey(age)) {
map.put(age, new ArrayList<>());
}
map.get(age).add(student);
}
return map;
}
// Find a student by name (returns null if not found)
public Student findStudentByName(String name) {
for (Student student : students) {
if (student.getName().equals(name)) {
return student;
}
}
return null;
}
// Get student count
public int getStudentCount() {
return students.size();
}
}
Création de l'application principale
Maintenant, créons notre application principale qui utilise la classe StudentManager. Créez un fichier nommé StudentManagementApp.java :
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class StudentManagementApp {
private static StudentManager manager = new StudentManager();
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
// Add some sample students
initializeData();
boolean running = true;
while (running) {
displayMenu();
int choice = getIntInput("Enter your choice: ");
switch (choice) {
case 1:
addStudent();
break;
case 2:
displayAllStudents();
break;
case 3:
displayTopStudents();
break;
case 4:
displayStudentsSortedByName();
break;
case 5:
displayStudentsSortedByAge();
break;
case 6:
displayStudentsAboveGrade();
break;
case 7:
displayStudentsGroupedByAge();
break;
case 8:
findStudent();
break;
case 9:
running = false;
break;
default:
System.out.println("Invalid choice. Please try again.");
}
System.out.println(); // Empty line for better readability
}
System.out.println("Thank you for using the Student Management System.");
scanner.close();
}
private static void displayMenu() {
System.out.println("===== Student Management System =====");
System.out.println("1. Add a new student");
System.out.println("2. Display all students");
System.out.println("3. Display top students by grade");
System.out.println("4. Display students sorted by name");
System.out.println("5. Display students sorted by age");
System.out.println("6. Display students above a grade threshold");
System.out.println("7. Display students grouped by age");
System.out.println("8. Find a student by name");
System.out.println("9. Exit");
}
private static void initializeData() {
manager.addStudent(new Student("Alice", 20, 85.5));
manager.addStudent(new Student("Bob", 22, 90.0));
manager.addStudent(new Student("Charlie", 19, 78.3));
manager.addStudent(new Student("David", 21, 85.5));
manager.addStudent(new Student("Eve", 20, 92.7));
}
private static void addStudent() {
System.out.println("=== Add a new student ===");
String name = getStringInput("Enter student name: ");
int age = getIntInput("Enter student age: ");
double grade = getDoubleInput("Enter student grade: ");
manager.addStudent(new Student(name, age, grade));
System.out.println("Student added successfully.");
}
private static void displayAllStudents() {
System.out.println("=== All Students ===");
List<Student> students = manager.getAllStudents();
displayStudents(students);
}
private static void displayTopStudents() {
int count = getIntInput("Enter the number of top students to display: ");
System.out.println("=== Top " + count + " Students ===");
List<Student> topStudents = manager.getTopStudents(count);
displayStudents(topStudents);
}
private static void displayStudentsSortedByName() {
System.out.println("=== Students Sorted by Name ===");
List<Student> sortedStudents = manager.getStudentsSortedByName();
displayStudents(sortedStudents);
}
private static void displayStudentsSortedByAge() {
System.out.println("=== Students Sorted by Age ===");
List<Student> sortedStudents = manager.getStudentsSortedByAge();
displayStudents(sortedStudents);
}
private static void displayStudentsAboveGrade() {
double threshold = getDoubleInput("Enter the grade threshold: ");
System.out.println("=== Students Above Grade " + threshold + " ===");
List<Student> filteredStudents = manager.getStudentsAboveGrade(threshold);
displayStudents(filteredStudents);
}
private static void displayStudentsGroupedByAge() {
System.out.println("=== Students Grouped by Age ===");
Map<Integer, List<Student>> groupedStudents = manager.getStudentsGroupedByAge();
for (Map.Entry<Integer, List<Student>> entry : groupedStudents.entrySet()) {
System.out.println("Age " + entry.getKey() + ":");
displayStudents(entry.getValue());
System.out.println();
}
}
private static void findStudent() {
String name = getStringInput("Enter the name of the student to find: ");
Student student = manager.findStudentByName(name);
if (student != null) {
System.out.println("=== Student Found ===");
System.out.println(student);
} else {
System.out.println("Student with name '" + name + "' not found.");
}
}
private static void displayStudents(List<Student> students) {
if (students.isEmpty()) {
System.out.println("No students to display.");
return;
}
for (Student student : students) {
System.out.println(student);
}
}
private static String getStringInput(String prompt) {
System.out.print(prompt);
return scanner.nextLine();
}
private static int getIntInput(String prompt) {
while (true) {
try {
System.out.print(prompt);
String input = scanner.nextLine();
return Integer.parseInt(input);
} catch (NumberFormatException e) {
System.out.println("Invalid input. Please enter a valid integer.");
}
}
}
private static double getDoubleInput(String prompt) {
while (true) {
try {
System.out.print(prompt);
String input = scanner.nextLine();
return Double.parseDouble(input);
} catch (NumberFormatException e) {
System.out.println("Invalid input. Please enter a valid number.");
}
}
}
}
Compilation et exécution de l'application
Compilons et exécutons notre système de gestion des étudiants :
javac Student.java StudentComparators.java StudentManager.java StudentManagementApp.java
java StudentManagementApp
Vous verrez maintenant un menu interactif qui vous permet de :
- Ajouter de nouveaux étudiants
- Afficher tous les étudiants
- Afficher les meilleurs étudiants par note
- Afficher les étudiants triés par nom
- Afficher les étudiants triés par âge
- Afficher les étudiants au-dessus d'un seuil de note
- Afficher les étudiants regroupés par âge
- Trouver un étudiant par nom
- Quitter l'application
Essayez les différentes options pour voir comment les différents mécanismes de comparaison que nous avons implémentés fonctionnent dans une application réelle. Par exemple :
- L'option 3 utilise le
GradeComparatorpour trouver les meilleurs étudiants par note - L'option 4 utilise le
NameComparatorpour trier les étudiants par nom - L'option 5 utilise le
AgeComparatorpour trier les étudiants par âge
Ce système de gestion des étudiants démontre comment les mécanismes de comparaison que nous avons appris peuvent être appliqués dans un scénario réel pour gérer et organiser efficacement les données.
Points clés à retenir
Grâce à ce lab, vous avez appris :
- Comment créer une classe Java avec plusieurs attributs
- Comment remplacer
equals()ethashCode()pour une comparaison d'objets correcte - Comment implémenter l'interface
Comparablepour définir un ordre naturel - Comment utiliser l'interface
Comparatorpour un ordre personnalisé - Comment appliquer ces concepts dans une application pratique
Ces compétences sont fondamentales pour tout développeur Java et seront utiles dans un large éventail d'applications, du traitement des données aux interfaces utilisateur.
Résumé
Dans ce lab, vous avez appris à comparer des objets Java en fonction de plusieurs attributs. Vous avez exploré trois mécanismes clés pour la comparaison d'objets en Java :
Remplacement des méthodes equals() et hashCode() : Vous avez appris à implémenter correctement ces méthodes pour vérifier si deux objets sont égaux en fonction de leur contenu.
Implémentation de l'interface Comparable : Vous avez découvert comment définir un ordre naturel pour vos objets en implémentant la méthode
compareTo(), ce qui vous permet de trier les objets en fonction de plusieurs attributs.Utilisation de l'interface Comparator : Vous avez exploré comment créer des comparateurs personnalisés pour trier les objets de différentes manières en fonction de divers critères.
Vous avez appliqué ces concepts pour construire un système de gestion des étudiants pratique qui démontre comment ces mécanismes de comparaison fonctionnent ensemble dans une application réelle.
Ces compétences sont fondamentales pour une programmation Java efficace, en particulier lorsque vous travaillez avec des collections d'objets qui doivent être triés, filtrés ou comparés. Comprendre la comparaison d'objets vous permet de créer des applications plus efficaces et robustes.
Continuez à pratiquer ces techniques, car elles seront inestimables dans votre parcours en tant que développeur Java.



