Map<String, Map<String, Car>> to List<Car> using Java 8

RubioRic :

Let's say that I have the structure described in the title:

Map<String, Map<String, Car>> mapNeighborhood

that contains all cars in a neighborhood indexed by address and plate respectively. I want to select all red cars to repaint them in black. To accomplish that task, I have tried to "flat" both Maps and obtain a List using Java 8. Once I got the List, applying a Predicate I can select only the red cars and apply the repainting.

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));

I'm sure that you can achieve the same using just one line in Java 8, but I think that you may lose legibility.

My question is: Is there another less verbose way of flattening the Maps into a List? Maybe using flatMap. Thanks in advance.

Boris the Spider :

You don't need an intermediate List

mapNeighborhood.values().stream()
                        .flatMap(byPlate -> byPlate.values().stream())
                        .filter(Car::isRed)
                        .forEach(car -> car.repaint(Color.Black))

I think this is both more readable than your code and shorter. It is also objectively much more efficient, both in time and space.


Also note that Car::isRed is somewhat odd as you would need a check for every possible Color on Car - add a new color for the season, reimplement Car.

Color::isRed makes much more sense, with Car implements Colored or some such

interface Colored {
    Color getColor();
}

// in Color
public static boolean isRed(Colored colored) {
    return Objects.equals(colored.getColor(), RED);
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=84988&siteId=1