J'ai rencontré le cas où j'ai besoin de convertir La classe elle-même ressemble à la manière suivante (j'ai omis les getters / setters et les constructeurs): Je veux mapper tous les livres avec certaines clés uniques, donc la probabilité de duplication est soit négligeable soit J'ai essayé de le faire de cette façon: Cela fonctionne mais cela a l'air moche, difficilement lisible et pas très agréable à avoir dans la base de code car cela peut dérouter mes collègues. Existe-t-il un meilleur moyen List
en Map
et la seule solution que je peux trouver est de savoir comment faire Map Map<String, Book> booksByAsinAndTitle = books.stream()
.collect(Collectors.groupingBy((book) -> book.getAsin() + "||" + book.getTitle()))
.entrySet()
.stream()
.collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue().get(0)));
0
.public class Book {
private String asin;
private String author;
private String title;
}
java 8
d’obtenir le même résultat?
3 Réponses :
Vous n'avez pas besoin de regrouper vos livres si vous êtes sûr que les clés sont uniques.
Map<String, Book> booksByAsinAndTitle = books.stream() .collect(Collectors.toMap(book -> book.getAsin() + "||" + book.getTitle(), x -> x));
Utilisez toMap
au lieu de groupingBy
:
Map<String, Book> booksByAsinAndTitle = books.stream() .collect(Collectors.toMap(b -> b.getAsin() + "||" + b.getTitle(), Function.identity()), (a,b) -> a);
Si la clé selon laquelle vous groupez est unique, il n'y a aucune raison de utilisez groupingBy
.
Si votre clé n'est peut-être pas unique et que vous voulez toujours que la Map
contienne la première valeur correspondant à une clé donnée, ajoutez un fonction de fusion:
Map<String, Book> booksByAsinAndTitle = books.stream() .collect(Collectors.toMap(b -> b.getAsin() + "||" + b.getTitle(), Function.identity()));
Y aura-t-il une différence si ma clé ne sera pas unique et que je déciderai de prendre le premier élément?
@DmytroChasovskyi vous devrez ajouter une fonction de fusion dans ce cas
Eh bien, j'y pensais en postant ma réponse aussi. (a, b) -> a
garantirait-il .get (0)
?
@nullpointer bien, je pense que c'est plus correct que .get (0), puisque groupingBy ne dit rien sur l'ordre des éléments dans la liste d'un groupe donné. .get (0) peut ou non retourner le premier livre (selon l'ordre de la liste d'origine) qui correspond à une clé donnée.
@Eran Apparemment, groupingBy
préserve l'ordre. stackoverflow.com/questions/39172981/… < / a>
Une représentation plus simple de la même chose en utilisant Map.putIfAbsent
et forEach
seraient:
Function<Book, String> primaryKey = book -> book.getAsin() + "||" + book.getTitle(); Map<String, Book> booksByAsinAndTitle = new HashMap<>(); books.forEach(book -> booksByAsinAndTitle.putIfAbsent(primaryKey.apply(book), book));
Remarque : Cela garantit que le premier livre
trouvé sur une clé reste dans la carte.