2016-03-07 121 views
5

試圖通過一個簡單的例子讓我的腦袋圍繞Java 8流語法。看看關於這個主題的其他類似問題,但找不到任何符合我的例子並能爲我工作的解決方案。基本上我想有兩個嵌套循環重構下面的代碼片段使用新的流API:Java 8嵌套循環到流

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; 

好不容易纔想出這個返回無效:

return cars.stream().forEach(
      car -> wheels.stream() 
      .filter(wheel -> wheel.getColor() == car.getColor() && 
        wheel.isWorking() == true) 
      .collect(Collectors.toList())); 

什麼是錯流上面的語法,我錯過了什麼?

+6

作爲一般建議,停止首先查看'forEach'的行爲。一旦你理解了這一點,並且總是先看其他流操作,那麼你可能再也不會問這樣的問題了。除此之外,不要使用像'wheel.isWorking()== true'這樣的條件,它們是毫無意義的。只需使用'wheel.isWorking()',它就會自己說明問題。 – Holger

回答

9

您不能在同一Stream上執行兩個終端操作 - forEachcollect

相反,你需要通過檢查每一輛汽車,如果它有一個匹配的工作輪篩選汽車名單:​​

List<Car> filteredCars = 
    cars.stream() 
     .filter (
      car -> wheels.stream() 
         .anyMatch(wheel -> wheel.getColor() == car.getColor() &&  
              wheel.isWorking())) 
     .collect(Collectors.toList()); 
2

的問題是,要創建的List(S)的forEach內, forEach返回void。這將是等效的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) !!! 

你可以在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());