1. Recherche d’éléments dans les collections
Recherche avec les méthodes standard
Lorsque nous avons une liste, par exemple de prénoms :
List<String> names = List.of("Anna", "Boris", "Victoria", "Anna", "Dany");
Java propose plusieurs méthodes pratiques de recherche :
- contains(Object o) — vérifie si l’élément est présent dans la collection.
- indexOf(Object o) — renvoie le premier indice d’occurrence de l’élément (ou -1 s’il n’est pas trouvé).
- lastIndexOf(Object o) — renvoie le dernier indice d’occurrence de l’élément (ou -1).
Exemples :
System.out.println(names.contains("Anna")); // true
System.out.println(names.indexOf("Anna")); // 0
System.out.println(names.lastIndexOf("Anna")); // 3
System.out.println(names.contains("Serge")); // false
Fait : Pour les collections de type Set, il n’existe pas de méthodes indexOf et lastIndexOf — un Set n’a pas d’indices, seulement des valeurs uniques.
Recherche conditionnelle
Parfois, il faut trouver non pas une valeur précise, mais un élément qui satisfait une condition. Par exemple, trouver le premier prénom de plus de 6 caractères. Une boucle for classique convient parfaitement : dès que vous avez trouvé l’élément adéquat — utilisez break.
List<String> names = List.of("Anna", "Boris", "Victoria", "Anna", "Dany");
String found = null;
for (String name : names) {
if (name.length() > 6) {
found = name;
break; // Premier élément correspondant trouvé, on peut sortir de la boucle
}
}
System.out.println(found); // Victoria
Recherche des valeurs maximale et minimale
Pour les collections dont les éléments sont comparables (par exemple des nombres), on peut rapidement trouver le maximum et le minimum à l’aide de la classe Collections.
List<Integer> numbers = List.of(10, 5, 20, 7, 20, 3);
int max = Collections.max(numbers); // 20
int min = Collections.min(numbers); // 3
System.out.println("Maximum: " + max);
System.out.println("Minimum: " + min);
Important : Les éléments doivent être comparables (implémenter Comparable), sinon il faudra fournir un comparateur.
2. Tri des collections
Tri par défaut d’une liste
On ne peut trier que des listes modifiables (par exemple, ArrayList, LinkedList). Les collections de type Set et Map ne prennent pas en charge le tri directement.
Par défaut, le tri suit l’« ordre naturel » : pour les nombres — croissant, pour les chaînes — ordre alphabétique.
List<Integer> numbers = new ArrayList<>(List.of(5, 1, 7, 3));
Collections.sort(numbers);
System.out.println(numbers); // [1, 3, 5, 7]
On peut faire la même chose via la méthode de liste sort :
List<Integer> numbers = new ArrayList<>(List.of(5, 1, 7, 3));
numbers.sort(null); // null signifie : utiliser l'ordre naturel
System.out.println(numbers); // [1, 3, 5, 7]
Tri avec un comparateur
Si vous avez besoin d’une règle personnalisée — par exemple, trier des chaînes par longueur :
List<String> words = new ArrayList<>(List.of("chat", "éléphant", "mouche", "rhinocéros"));
words.sort(Comparator.comparingInt(String::length));
System.out.println(words); // [chat, mouche, éléphant, rhinocéros]
En ordre inverse :
words.sort(Comparator.comparingInt(String::length).reversed());
System.out.println(words); // [rhinocéros, éléphant, mouche, chat]
Ancien style via Collections.sort :
Collections.sort(words, Comparator.comparingInt(String::length));
3. Particularités du tri selon les collections
Le tri ne s’applique qu’aux listes
Les méthodes de tri (sort, Collections.sort) ne fonctionnent qu’avec les collections qui maintiennent un ordre des éléments (par exemple, List). Pour Set et Map, de telles méthodes ne sont pas prévues.
Tentative de trier un Set :
Set<Integer> mySet = new HashSet<>(List.of(3, 1, 2));
Collections.sort(mySet); // Erreur de compilation : sort attend un List !
Si vous devez obtenir une liste triée à partir d’un Set :
List<Integer> sortedFromSet = new ArrayList<>(mySet);
Collections.sort(sortedFromSet);
System.out.println(sortedFromSet); // [1, 2, 3]
Tri d’une Map : par clés et par valeurs
On ne peut pas trier une Map directement, mais on peut :
- Obtenir la liste des paires « clé–valeur »
- La trier comme souhaité
- Si nécessaire, construire une nouvelle Map
Exemple : tri par valeurs
Map<String, Integer> scores = Map.of(
"Anna", 15,
"Boris", 20,
"Victoria", 12
);
List<Map.Entry<String, Integer>> entries = new ArrayList<>(scores.entrySet());
entries.sort(Map.Entry.comparingByValue());
for (Map.Entry<String, Integer> entry : entries) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Victoria: 12
// Anna: 15
// Boris: 20
Trier des objets par champ
Supposons que nous ayons une classe d’utilisateur :
class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + " (" + age + ")";
}
}
Et une liste d’utilisateurs :
List<User> users = new ArrayList<>(List.of(
new User("Anna", 22),
new User("Boris", 18),
new User("Victoria", 25)
));
Tri par âge :
users.sort(Comparator.comparingInt(u -> u.age));
System.out.println(users); // [Boris (18), Anna (22), Victoria (25)]
En ordre inverse :
users.sort(Comparator.comparingInt((User u) -> u.age).reversed());
System.out.println(users); // [Victoria (25), Anna (22), Boris (18)]
4. Erreurs courantes lors de la recherche et du tri des collections
Erreur n°1 : trier une liste immuable. Les listes créées via List.of(...) ne peuvent pas être modifiées — un appel à sort lèvera UnsupportedOperationException.
List<Integer> immutable = List.of(3, 1, 2);
immutable.sort(null); // Lève une exception !
Erreur n°2 : trier directement un Set ou une Map. Les méthodes de tri ne fonctionnent pas avec Set et Map. Si vous devez trier, transformez d’abord les données en liste.
Erreur n°3 : mauvaise comparaison d’objets. N’effectuez pas de soustraction d’entiers « brute » lors d’une comparaison — des dépassements peuvent se produire. Au lieu de u1.age - u2.age, utilisez Integer.compare ou Comparator.comparingInt.
// users.sort((u1, u2) -> u1.age - u2.age); // Fonctionne, mais dangereux en cas de dépassement !
Erreur n°4 : utiliser contains pour une recherche complexe. La méthode contains vérifie uniquement l’égalité stricte (via equals). Si vous devez chercher par sous-chaîne ou par champ d’objet — utilisez une boucle avec une condition ou des comparateurs/streams.
GO TO FULL VERSION