Tri des collections par plusieurs champs en Kotlin : 5 erreurs fatales

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi un tri « simple » en Kotlin casse-t-il le code ?

\n

Bonjour, collègue ! Si tu as déjà programmé en Kotlin et essayé de trier une liste de tâches d'abord par date, puis par priorité, tu as sûrement rencontré une situation où le résultat ressemble à un ensemble aléatoire. Tu n'es pas seul — la question « Sort collection by multiple fields in Kotlin » a recueilli des milliers de vues sur Stack Overflow. Quoi de plus simple, apparemment ? Mais le diable, comme toujours, se cache dans les détails.

\n

Dans cet article, nous allons analyser les meilleures erreurs lors du tri par plusieurs champs en Kotlin, que même les développeurs expérimentés commettent. Tu découvriras comment fonctionne sortedWith, pourquoi compareBy et thenBy sont tes meilleurs amis, et comment ne pas perdre de données à cause de null. C'est parti !

\n\n

Erreur n°1 : Trier comme en Java — avec un Comparator manuel

\n

Kotlin n'est pas Java. Mais beaucoup, venant du monde Java, écrivent :

\n
val list = listOf(\n    User("Alice", 25),\n    User("Bob", 20),\n    User("Charlie", 25)\n)\n\nval sorted = list.sortedWith(Comparator { a, b ->\n    val ageCompare = a.age.compareTo(b.age)\n    if (ageCompare != 0) ageCompare else a.name.compareTo(b.name)\n})\n
\n

Oui, cela fonctionne. Mais c'est terriblement illisible, et tu peux facilement te perdre dans les chaînes de if-else. Kotlin propose une manière élégante — les fonctions de comparaison.

\n

Comment faire correctement ?

\n
val sorted = list.sortedWith(compareBy<User> { it.age }.thenBy { it.name })\n
\n

Court, clair, sans logique superflue. compareBy crée un comparateur principal, et thenBy ajoute des champs secondaires. C'est le tri par plusieurs champs en Kotlin dans sa forme idéale.

\n\n

Erreur n°2 : Ignorer les null lors du tri

\n

Supposons que nous ayons une liste de tâches où deadline peut être null. Si tu écris simplement :

\n
tasks.sortedBy { it.deadline }\n
\n

…tu obtiendras une NullPointerException. Kotlin est strict avec null, et c'est parfait. Mais que faire si null est normal ?

\n

Solution : nullsFirst / nullsLast

\n

Utilise des wrappers spéciaux :

\n
val sorted = tasks.sortedWith(\n    compareBy<Task>(nullsLast()) { it.deadline }\n        .thenBy { it.priority }\n)\n
\n

Ici, nullsLast() place toutes les dates null à la fin de la liste. Il existe aussi nullsFirst() — l'inverse. Cela résout le problème, et ton tri de collections Kotlin devient sûr.

\n\n

Erreur n°3 : Confusion entre sortedBy et sortedWith

\n

Beaucoup de débutants écrivent :

\n
list.sortedBy { it.age }.sortedBy { it.name }\n
\n

Et sont surpris que le tri par nom « écrase » le tri par âge. sortedBy crée à chaque fois une nouvelle liste et ne trie que par un seul champ. Le dernier appel est le principal.

\n

Comment corriger ?

\n

Utilise sortedWith avec une chaîne de compareBy :

\n
list.sortedWith(compareBy({ it.age }, { it.name }))\n
\n

Ou une version multiligne pour une logique complexe :

\n
list.sortedWith(compareBy<Person> { it.age }.thenByDescending { it.name })\n
\n

Rappelle-toi : un seul appel à sortedWith — un seul tri par plusieurs champs.

\n\n

Erreur n°4 : Tri dans l'ordre inverse — au mauvais endroit

\n

Parfois, il faut trier par âge croissant, mais par nom décroissant. Erreur typique :

\n
list.sortedByDescending { it.age }.sortedBy { it.name }\n
\n

Encore le même problème — le deuxième tri casse le premier. La bonne approche :

\n
val sorted = list.sortedWith(\n    compareBy<Person> { it.age }\n        .thenByDescending { it.name }\n)\n
\n

Ou pour un contrôle total :

\n
val sorted = list.sortedWith(\n    compareBy(Person::age).thenByDescending(Person::name)\n)\n<                

Blogs

Book Recommendations