[英]Java 8 nested loops to stream
Trying to get my head round the Java 8 streams syntax with a simple example. 试着通过一个简单的例子来了解Java 8流语法。 Had a look at the other similar questions on this topic, but could not find any solutions that would match my example and would work for me. 看看关于这个主题的其他类似问题,但找不到任何与我的例子相符的解决方案,并且对我有用。 Basically I am trying to refactor the following snippet with two nested loops to use the new stream API: 基本上我正在尝试使用两个嵌套循环重构以下代码段以使用新的流API:
List<Car> filteredCars = new ArrayList<>();
for (Car car : cars) {
for (Wheel wheel : wheels) {
if (car.getColor() == wheel.getColor() &&
wheel.isWorking() == true ) {
filteredCars.add(car);
break;
}
}
}
return filteredCars;
Managed to come up with this which returns void: 管理得出这个返回void:
return cars.stream().forEach(
car -> wheels.stream()
.filter(wheel -> wheel.getColor() == car.getColor() &&
wheel.isWorking() == true)
.collect(Collectors.toList()));
What is wrong with the stream syntax above and what am I missing? 上面的流语法有什么问题,我错过了什么?
You can't perform two terminal operations - forEach
and collect
on the same Stream
. 您不能执行两个终端操作 - forEach
并在同一个Stream
上collect
。
instead, you need to filter the cars list by checking for each car if it has a matching working wheel : 相反,你需要通过检查每辆车是否有匹配的工作轮来过滤汽车列表:
List<Car> filteredCars =
cars.stream()
.filter (
car -> wheels.stream()
.anyMatch(wheel -> wheel.getColor() == car.getColor() &&
wheel.isWorking()))
.collect(Collectors.toList());
The problem is, you're creating the List
(s) inside the forEach
and forEach
returns void
. 问题是,你在forEach
创建了List
,而forEach
返回了void
。 This would be the equivalent of the following for loop: 这将等同于以下for循环:
for (Car car : cars) {
List<Car> filteredCars = new ArrayList<>();
for (Wheel wheel : wheels) {
if (car.getColor() == wheel.getColor() &&
wheel.isWorking() == true ) {
filteredCars.add(car);
break;
}
}
}
return filteredCars; // whoops cannot be accessed (scope) !!!
You could use filter
on the cars
stream and collect the use collect
on the filtered stream to achieve the desired results: 您可以在cars
流上使用filter
并在过滤后的流上收集使用collect
以获得所需的结果:
Predicate<Car> carCheck = car -> wheels.stream().anyMatch(wheel -> car.getColor() == wheel.getColor() && wheel.isWorking());
List<Car> filteredCars = cars.stream().filter(carCheck).collect(Collectors.toList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.