Oh, ces délicats Java 8 flux avec lambdas. Ils sont très puissants, mais les subtilités prennent un peu pour envelopper son en-tête autour de tout cela.
Disons que j'ai un type User
avec une propriété User.getName()
. Disons que j'ai une carte de ces utilisateurs Map<String, User>
Associés aux noms (noms d'utilisateur de connexion, par exemple). Disons en outre que j'ai une instance d'un comparateur UserNameComparator.INSTANCE
Pour trier les noms d'utilisateurs (peut-être avec des collateurs sophistiqués et autres).
Alors, comment puis-je obtenir une liste des utilisateurs sur la carte, triés par nom d'utilisateur? Je peux ignorer les clés de carte et faire ceci:
return userMap.values()
.stream()
.sorted((u1, u2) -> {
return UserNameComparator.INSTANCE.compare(u1.getName(), u2.getName());
})
.collect(Collectors.toList());
Mais cette ligne où je dois extraire le nom pour utiliser le UserNameComparator.INSTANCE
Semble être trop de travail manuel. Existe-t-il un moyen de fournir simplement User::getName
En tant que fonction de mappage, juste pour le tri, tout en récupérant les instances User
dans la liste collectée?
Bonus: que se passe-t-il si la chose sur laquelle je veux trier a deux niveaux de profondeur, comme User.getProfile().getUsername()
?
Ce que vous voulez, c'est Comparator#comparing
:
userMap.values().stream()
.sorted(Comparator.comparing(User::getName, UserNameComparator.INSTANCE))
.collect(Collectors.toList());
Pour la deuxième partie de votre question, vous utiliseriez simplement
Comparator.comparing(
u->u.getProfile().getUsername(),
UserNameComparator.INSTANCE
)