2016-03-07 17 views
5

Ich versuche, die Java 8 Streams Syntax mit einem einfachen Beispiel zu verstehen. Ich habe mir die anderen ähnlichen Fragen zu diesem Thema angesehen, konnte aber keine Lösungen finden, die zu meinem Beispiel passen würden und für mich funktionieren würden. Grundsätzlich versuche ich, die folgenden Ausschnitt mit zwei verschachtelten Schleifen Refactoring den neuen Stream-API zu verwenden:Java 8 verschachtelte Schleifen zu streamen

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, um mit dieser die void zurückgibt:

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

Was mit dem Strom ist falsch Syntax oben und was fehlt mir?

+6

Als allgemeine Ratschlag, hör auf das Verhalten von "forEach" zu betrachten. Sobald Sie das verstanden haben und sich immer zuerst die anderen Stream-Operationen ansehen, werden Sie diese Frage wahrscheinlich nie mehr stellen müssen. Verwenden Sie außerdem keine Bedingungen wie 'wheel.isWorking() == true', sie sind sinnlos. Verwenden Sie einfach 'wheel.isWorking()', es spricht für sich. – Holger

Antwort

9

Sie können nicht zwei Terminaloperationen ausführen - forEach und collect auf demselben Stream.

statt, müssen Sie die Autos Liste filtern, indem für jedes Auto, zu prüfen, ob es eine passende Arbeits Rad hat:

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

Das Problem ist, du bist die List (n) innerhalb des forEach Schaffung und forEach gibt void zurück. Dies wäre das Äquivalent der folgenden for-Schleife:

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) !!! 

Sie filter auf dem cars Strom verwenden könnte und die Verwendung collect auf dem gefilterten Strom sammeln die gewünschten Ergebnisse zu erzielen:

Predicate<Car> carCheck = car -> wheels.stream().anyMatch(wheel -> car.getColor() == wheel.getColor() && wheel.isWorking()); 

List<Car> filteredCars = cars.stream().filter(carCheck).collect(Collectors.toList()); 
Verwandte Themen