Me encontré con el caso cuando necesito para convertir List<Book>
a Map<String, Book>
y las únicas soluciones que puedo encontrar es cómo hacerlo Map<String, List<Book>>
.
La clase en sí se ve de la siguiente manera (I omitido getters / setters y constructores):
public class Book {
private String asin;
private String author;
private String title;
}
Quiero mapear todos los libros de ciertas claves únicas, por lo que la probabilidad de duplicación es ya sea despreciable o 0
.
Traté de hacerlo de esta manera:
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)));
Funciona pero se ve feo, difícilmente legibles y no muy bueno tener en el código base, ya que puede confundir a mis colegas. ¿Hay alguna forma mejor java 8
manera de conseguir el mismo resultado?
Utilizar toMap
en lugar de groupingBy
:
Map<String, Book> booksByAsinAndTitle =
books.stream()
.collect(Collectors.toMap(b -> b.getAsin() + "||" + b.getTitle(),
Function.identity()));
Si la clave según el cual está agrupando es único, no hay razón para el uso groupingBy
.
Si la clave no puede ser única, y todavía quiere que el Map
que contiene el primer valor que coincide con una clave dada, añadir una función de combinación:
Map<String, Book> booksByAsinAndTitle =
books.stream()
.collect(Collectors.toMap(b -> b.getAsin() + "||" + b.getTitle(),
Function.identity()),
(a,b) -> a);