假设我有标题中描述的结构:
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"));