map<string, map<string, car>><Car> to list using Java 8



假设我有标题中描述的结构:

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

分别包含分别由地址和板块索引的邻里中的所有汽车。我想选择所有红色汽车以黑色重新粉刷它们。为了完成该任务,我尝试"平整"两个地图并使用Java 8获得列表8。一旦我获得了列表,应用了谓词,我只能选择红色汽车并应用重新粉刷。

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

我敢肯定,您可以在Java 8中只使用一行仅实现同样的方法,但是我认为您可能会失去可读性。

我的问题是:是否还有另一种将地图缩放到列表中的详细方法?也许使用flatMap。预先感谢。

您不需要中级List

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

我认为这两个比您的代码更可读,并且更短。它也是客观地在时间和空间上都更加高效。


另外,请注意,Car::isRed有些奇怪,因为您需要对Car上的每项可能的Color进行检查 - 为季节添加新的color,重新实现Car

Color::isRed使用Car实现Colored或某些此类

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

我的结果与@boris相同,但我将向您展示如何使用Intellij:

来实现它
for (Map<String, Car> value : mapNeighborhood.values()) {
    for (Car car : value.values()) {
        if (car.isRed()) {
            car.repaint(Color.BLACK);
        }
    }
}

然后,将光标移动到第一个" for" Word,按Alt-Enter,然后选择"替换为foreach",tada,我们在这里:

mapNeighborhood.values().stream()
                        .flatMap(value -> value.values().stream())
                        .filter(Car::isRed)
                        .forEach(car -> car.repaint(Color.BLACK));

使用任何类型的循环,您可以尝试使用Intellij来帮助您转换为Java 8样式智能

这是我尝试的一种方式

List<Car> collect = mapNeighborhood.values().stream()
                                            .map(Map::values)
                                            .flatMap(Collection::stream)
                                            .collect(Collectors.toList());

然后,您可以继续操纵汽车列表。

这可以有用。

mapNeighborhood.values().stream()
                        .map(Map::values)
                        .flatMap(Collection::stream)
                        .filter(car -> car.getColor().equalsIgnoreCase("red"))
                        .forEach(car -> car.repaint("black"));

最新更新