Vamos a decir que he la estructura descrita en el título:
Map<String, Map<String, Car>> mapNeighborhood
que contiene todos los coches en un barrio indexado por la dirección y la placa, respectivamente. Quiero seleccionar todos los coches rojos que volver a pintar en negro. Para llevar a cabo esta tarea, he tratado de "plana" Ambos mapas y obtener una lista utilizando Java 8. Una vez que consiguiera la lista, la aplicación de un predicado que puedo seleccionar sólo los coches rojos y aplicar el repintado.
List<Car> listCars = new ArrayList<Car>();
mapNeighborhood.values().forEach(map -> map.values()
.forEach(car -> listCars.add(car)));
listCars.stream().filter(Car::isRed)
.forEach(car -> car.repaint(Color.Black));
Estoy seguro de que se puede lograr lo mismo usando sólo una línea en Java 8, pero creo que puede perder legibilidad.
Mi pregunta es: ¿Hay otra manera menos detallado de aplanar los mapas en una lista? Tal vez el uso flatMap
. Gracias por adelantado.
No es necesario un intermedio List
mapNeighborhood.values().stream()
.flatMap(byPlate -> byPlate.values().stream())
.filter(Car::isRed)
.forEach(car -> car.repaint(Color.Black))
Creo que esto es tanto más fácil de leer que su código y más corto. También es objetivamente mucho más eficiente, tanto en el tiempo y en el espacio.
También nota que Car::isRed
es un poco extraño, ya que se necesita una comprobación para cada posible Color
en Car
- añadir nuevo color
para la temporada, reimplementar Car
.
Color::isRed
tiene mucho más sentido, con Car
implementos Colored
o algo así
interface Colored {
Color getColor();
}
// in Color
public static boolean isRed(Colored colored) {
return Objects.equals(colored.getColor(), RED);
}