Comparateur Java8 - Explication détaillée de la façon de trier une liste
Dans cet article, nous verrons plusieurs instructions sur la façon de trier une Liste en Java 8 Exemple.
List<String> cities = Arrays.asList( "Milan", "london", "San Francisco", "Tokyo", "New Delhi" ); System.out.println(cities); //[Milan, london, San Francisco, Tokyo, New Delhi] cities.sort(String.CASE_INSENSITIVE_ORDER); System.out.println(cities); //[london, Milan, New Delhi, San Francisco, Tokyo] cities.sort(Comparator.naturalOrder()); System.out.println(cities); //[Milan, New Delhi, San Francisco, Tokyo, london]
Le "L" de Londres utilise des lettres minuscules pour mieux mettre en évidence Comparator.naturalOrder() (retourne en premier Différence entre un comparateur qui trie les majuscules lettres) et String.CASE_INSENSITIVE_ORDER (un comparateur qui renvoie des lettres insensibles à la casse).
Basiquement, dans Java 7 nous avons Collection.sort() qui accepte une liste et enfin un Comparator - dans Java 8 nous avons le nouveau List.sort() qui accepte un Comparator.
List<Integer> numbers = Arrays.asList(6, 2, 1, 4, 9); System.out.println(numbers); //[6, 2, 1, 4, 9] numbers.sort(Comparator.naturalOrder()); System.out.println(numbers); //[1, 2, 4, 6, 9]
Supposons que nous ayons une classe Movie et que nous voulions " par titre "titre" trie la liste. Nous pouvons utiliser Comparator.comparing() , en passant une fonction qui extrait le champ utilisé pour trier le titre - dans ce cas.
List<Movie> movies = Arrays.asList( new Movie("Lord of the rings"), new Movie("Back to the future"), new Movie("Carlito's way"), new Movie("Pulp fiction")); movies.sort(Comparator.comparing(Movie::getTitle)); movies.forEach(System.out::println);
Sortie :
Movie{title='Back to the future'} Movie{title='Carlito's way'} Movie{title='Lord of the rings'} Movie{title='Pulp fiction'}
Vous remarquerez peut-être que nous ne transmettons aucun comparateur, mais que la liste est triée correctement. En effet, le titre - le champ extrait - est une chaîne et les chaînes implémentent l'interface Comparable . Si vous regardez l'implémentation de Comparator.comparing(), vous verrez qu'elle appelle compareTo sur la clé extraite.
return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
De la même manière, nous pouvons utiliser Comparator.comparingDouble() pour comparer des valeurs doubles. Dans l'exemple, nous souhaitons classer la liste des films de la note la plus élevée à la note la plus basse.
List<Movie> movies = Arrays.asList( new Movie("Lord of the rings", 8.8), new Movie("Back to the future", 8.5), new Movie("Carlito's way", 7.9), new Movie("Pulp fiction", 8.9)); movies.sort(Comparator.comparingDouble(Movie::getRating) .reversed()); movies.forEach(System.out::println);
Nous utilisons la fonction inversée du comparateur afin d'inverser l'ordre naturel par défaut du plus bas au plus élevé. Comparator.comparingDouble() utilise Double.compare() en interne.
Si vous avez besoin de comparer int ou long, vous pouvez utiliser comparantInt() et comparantLong() respectivement.
Dans l'exemple précédent, nous n'avons spécifié aucun comparateur car ce n'était pas nécessaire, mais voyons un exemple où nous avons défini notre propre comparateur. Notre classe Movie a un nouveau champ - "starred" - défini à l'aide du troisième paramètre constructeur . Dans l'exemple, nous souhaitons trier la liste afin que les films favoris soient en haut de la liste.
List<Movie> movies = Arrays.asList( new Movie("Lord of the rings", 8.8, true), new Movie("Back to the future", 8.5, false), new Movie("Carlito's way", 7.9, true), new Movie("Pulp fiction", 8.9, false)); movies.sort(new Comparator<Movie>() { @Override public int compare(Movie m1, Movie m2) { if(m1.getStarred() == m2.getStarred()){ return 0; } return m1.getStarred() ? -1 : 1; } }); movies.forEach(System.out::println);
Le résultat sera :
Movie{starred=true, title='Lord of the rings', rating=8.8} Movie{starred=true, title='Carlito's way', rating=7.9} Movie{starred=false, title='Back to the future', rating=8.5} Movie{starred=false, title='Pulp fiction', rating=8.9}
On peut bien sûr utiliser lambdaexpression à la place de la classe Anonyme comme ceci :
movies.sort((m1, m2) -> { if(m1.getStarred() == m2.getStarred()){ return 0; } return m1.getStarred() ? -1 : 1; });
Nous pouvons également utiliser Comparator.comparing() à nouveau :
movies.sort(Comparator.comparing(Movie::getStarred, (star1, star2) -> { if(star1 == star2){ return 0; } return star1 ? -1 : 1; }));
Dans le dernier exemple, Comparator.comparing() prend le premier argument comme une fonction qui extrait la clé utilisée pour le tri, et passe Comparator comme deuxième paramètre. Le comparateur utilise des clés extraites à des fins de comparaison, star1 et star2 sont en réalité des valeurs booléennes, représentant respectivement m1.getStarred() et m2.getStarred().
Dans le dernier exemple, nous allons classer les films favoris, puis trier par note.
List<Movie> movies = Arrays.asList( new Movie("Lord of the rings", 8.8, true), new Movie("Back to the future", 8.5, false), new Movie("Carlito's way", 7.9, true), new Movie("Pulp fiction", 8.9, false)); movies.sort(Comparator.comparing(Movie::getStarred) .reversed() .thenComparing(Comparator.comparing(Movie::getRating) .reversed()) ); movies.forEach(System.out::println);
Le résultat est :
Movie{starred=true, title='Lord of the rings', rating=8.8} Movie{starred=true, title='Carlito's way', rating=7.9} Movie{starred=false, title='Pulp fiction', rating=8.9} Movie{starred=false, title='Back to the future', rating=8.5}
Comme vous pouvez le voir, nous trions d'abord par étoiles, puis par note - les deux étant inversés parce que nous voulons la valeur la plus élevée et la valeur réelle numéro un.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!