【发布时间】:2019-06-05 11:15:10
【问题描述】:
我是 java 8 的新手,我需要重写一段旧代码来实现新的算法。 任务是为每个列表过滤具有最大速度的对象。 列表嵌套在地图中:道路的根地图,其中包含路段的地图,每个路段地图包含一个对象列表,每个对象都描述了在某个时间间隔内测得的速度。我需要找到每个列表的所有最大速度。
我发现以下链接看起来像我的问题,但我无法调整它们,而且我不确定我的尝试是否能正确解决我的问题。
How do you filter nested loops using Java 8 streams and filters?
Java 8 Filter Map<String,List<Employee>>
这是我用来编写我的示例的代码
Map<String, Map<String, Employee>> employeeMap =
employeeMap.entrySet()
.stream()
.collect(toMap(Map.Entry::getKey,
e -> e.getValue().entrySet().stream()
.filter(emp -> !emp.getValue().getState().equals("MI"))
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue))));
for(Car car : cars) {
for (Engine engine : car.getEngines()) {
for (Part part : engine.getParts()) {
// ...
}
}
}
cars.stream()
.flatMap(car -> car.getEngines().stream())
.flatMap(engine -> engine.getParts().stream())
.forEach(part -> { ... });
这是我的结果代码
Map<Integer, Map<Integer, List<PartialSpeed>>> speedsPerRoadPerSegment;
ArrayList<PartialSpeed> maxSpeedPerSegment = new ArrayList<PartialSpeed>();
speedsPerRoadPerSegment.entrySet().stream()
.forEach(road-> road.getValue().entrySet()
.stream()
.forEach(segment ->
{
Optional<PartialSpeed> result = segment.getValue().stream()
.max(Comparator.comparing(PartialSpeed::getnVelFfs));
maxSpeedPerSegment.add(result.get());
}));
我尝试遵守该示例的所有尝试都存在无法识别结果类型的问题。 这是我能做到的最好的(不工作):
speedsPerRoadPerSegment.entrySet().stream()
.flatMap(road-> road.getValue().entrySet()
.stream().flatMap(
segment -> segment .getValue()
.stream()
.max(Comparator.comparing(PartialSpeed::getnVelFfs))
));
如您所见,我刚刚用 foreaches 替换了旧的 for 循环。我想了解如何直接从 lambda 表达式中获取最大元素列表。
【问题讨论】:
-
Map<Road, Map<Segment, List<PartialSpeed>>>是 speedsPerRoadPerSegment 的类型? -
@Hadi j yes ,道路和路段只是整数 ID。我已经编辑了代码。如果有不清楚的地方请询问,我已将变量名称翻译成英文以使其更易于理解。
-
试试这个
speedsPerRoadPerSegment.entrySet() .forEach(road -> road.getValue().entrySet() .stream() .map(segment -> segment.getValue() .stream().max(Comparator.comparing(PartialSpeed::getnVelFfs))). map(Optional::get) .forEach(maxSpeedPerSegment ::add));我没测试过。 -
虽然 Holger 的回答很好,但也可以试试这个
speedsPerRoadPerSegment.entrySet() .stream() .flatMap(road -> road.getValue().entrySet().stream()) .map(Map.Entry::getValue) .filter(list->!list.isEmpty()) .map(segment -> segment.stream() .max(Comparator.comparing(PartialSpeed::getnVelFfs))) .map(Optional::get).collect(Collectors.toList()); -
@Hadi J +1 你的最后一个例子。它非常有用:我意识到我的错误是没有从 Map.Entry 中获得价值。我会坚持使用 Holger 解决方案,因为正如他所说,我必须选择正确的集合视图。
标签: java lambda java-8 java-stream