2016-03-07 17 views
5

Cố gắng thu hút đầu của tôi theo cú pháp luồng Java 8 với một ví dụ đơn giản. Đã xem xét các câu hỏi tương tự khác về chủ đề này, nhưng không thể tìm thấy bất kỳ giải pháp nào phù hợp với ví dụ của tôi và sẽ phù hợp với tôi. Về cơ bản tôi đang cố gắng để cấu trúc lại các đoạn sau đây với hai vòng lồng nhau để sử dụng các dòng API mới:Java 8 vòng lặp lồng nhau để dòng

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 đưa ra với điều này mà trả về void:

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

gì là sai với dòng cú pháp ở trên và tôi đang thiếu gì?

+6

Là một vị tướng lời khuyên, dừng lại hành vi của lần đầu tiên nhìn vào 'forEach'. Khi bạn đã hiểu điều đó và luôn xem xét các hoạt động khác của luồng đầu tiên, có thể bạn sẽ không bao giờ phải hỏi câu hỏi đó nữa. Bên cạnh đó, không sử dụng các điều kiện như 'wheel.isWorking() == true', chúng là vô nghĩa. Chỉ cần sử dụng 'wheel.isWorking()', nó tự nói lên. – Holger

Trả lời

9

Bạn không thể thực hiện hai thao tác đầu cuối - forEachcollect trên cùng một Stream.

thay vào đó, bạn cần phải lọc danh sách những chiếc xe bằng cách kiểm tra cho mỗi xe nếu nó có một khớp bánh xe làm việc:

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

Vấn đề là, bạn đang tạo List (s) bên trong forEachforEach trả về void. Đây sẽ là tương đương với các nội dung sau vòng lặp 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) !!! 

Bạn có thể sử dụng filter trên dòng cars và thu thập việc sử dụng collect trên dòng lọc để đạt được kết quả mong muốn:

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

List<Car> filteredCars = cars.stream().filter(carCheck).collect(Collectors.toList()); 
Các vấn đề liên quan