地图<;字符串,Map<;字符串,Car>&燃气轮机;列出<;汽车>;使用Java8
假设我有标题中描述的结构:地图<;字符串,Map<;字符串,Car>&燃气轮机;列出<;汽车>;使用Java8,java,java-8,flatten,Java,Java 8,Flatten,假设我有标题中描述的结构: Map<String, Map<String, Car>> mapNeighborhood 地图地图邻居 包含一个邻居中的所有汽车,分别按地址和车牌索引。 我想选择所有红色的车,把它们重新漆成黑色。为了完成这项任务,我尝试使用Java8“展开”这两个映射并获得一个列表。一旦我得到了这个列表,应用一个谓词,我就可以只选择红色的汽车并应用重新绘制 List<Car> listCars = new ArrayList<Car&g
Map<String, Map<String, Car>> mapNeighborhood
地图地图邻居
包含一个邻居中的所有汽车,分别按地址和车牌索引。
我想选择所有红色的车,把它们重新漆成黑色。为了完成这项任务,我尝试使用Java8“展开”这两个映射并获得一个列表。一旦我得到了这个列表,应用一个谓词,我就可以只选择红色的汽车并应用重新绘制
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));
List listCars=new ArrayList();
MapNeighborary.values().forEach(映射->映射.values())
.forEach(car->listCars.add(car));
listCars.stream().filter(Car::isRed)
.forEach(car->car.repaint(Color.Black));
我确信,在Java8中,只需使用一行代码就可以实现同样的效果,但我认为可能会丢失可读性
我的问题是:是否有另一种不那么冗长的方法将地图平铺成列表?可能使用
flatMap
。提前感谢。您不需要中间列表
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);
}
}
}
对于任何类型的循环,您都可以尝试使用IntelliJ来帮助您智能地转换为Java8样式
List<Car> collect = mapNeighborhood.values().stream()
.map(Map::values)
.flatMap(Collection::stream)
.collect(Collectors.toList());
List collect=mapNeighborhood.values().stream()
.map(映射::值)
.flatMap(集合::流)
.collect(Collectors.toList());
然后,您可以继续操作汽车列表。这会很有帮助
mapNeighborhood.values().stream()
.map(Map::values)
.flatMap(Collection::stream)
.filter(car -> car.getColor().equalsIgnoreCase("red"))
.forEach(car -> car.repaint("black"));
你说得对,你的解决方案完全可读,而且比我的更有效。:-)这就是我要找的。我觉得我的太冗长和无能了。我真正的课程不是汽车,这不是家庭作业,方法汽车::isRed只是一个比喻,但我会把你所说的保留在我的课堂上。非常感谢你!好把戏!我使用Eclipse,我不熟悉IntelliJ,但我喜欢你的答案。谢谢<代码>映射邻域.values().forEach(value->value.values().forEach(car->rePiantIfRed(car))代码>@HadiJ好吧,这几乎是我最初的解决方案,但将过滤隐藏在方法“repaintfred”中。谢谢你的评论。@HadiJ我已经用你的方法删除了一个多余的流()。谢谢:-)
mapNeighborhood.values().stream()
.map(Map::values)
.flatMap(Collection::stream)
.filter(car -> car.getColor().equalsIgnoreCase("red"))
.forEach(car -> car.repaint("black"));