2016-03-02 19 views
7

Có cách nào để xem nhanh phần tử tiếp theo trong luồng không? Ý tưởng tăng từ một dòng của một danh sách các đối tượng, nơi mà hai đối tượng sau đây cần được so sánh (để làm mịn một số khác biệt, nhưng điều đó không quan trọng ở đây). Là một for loop cũ này sẽ như thế nào:Peek phần tử tiếp theo trong luồng

List<Car> autobahn = getCars(); 
for (int i = 0; i < autobahn.size()-1; i++) { 
    if(autobahn.get(i).speed>autobahn.get(i+1).speed) 
     autobahn.get(i).honk(); 
} 

Cách tốt nhất cho đến nay như dòng sẽ là:

autobahn.stream() 
      .limit(autobahn.size()-1) 
      .filter(car -> car.speed < autobahn.get(autobahn.indexOf(car)+1).speed) 
      .forEach(car -> car.honk()); 

Các chính-vấn đề với giải pháp này là phương pháp indexOf, vì có thể có hai lần cùng một chiếc xe trên autobahn. Một giải pháp tốt hơn sẽ có một số cách để nhìn trộm tiếp theo (hoặc một trước đó) phần tử (với một lớp giúp đỡ, điều này có thể thậm chí có thể, nhưng trông khủng khiếp)

BoxedCar boxedCar = new BoxedCar(autobahn.get(0)); 
autobahn.stream() 
      .skip(1) 
      .filter(car -> boxedCar.setContent(car)) 
      .forEach(car -> car.winTheRace()); 

với helperclass

class BoxedCar { 

    Car content; 

    BoxedCar(Car content) { 
     this.content = content; 
    } 
    boolean setContent(Car content) { 
     double speed = this.content.speed; 
     this.content = content; 
     return content.speed > speed; 
    } 
} 

hoặc để chuyển hướng Stream<Car> thành một loại Stream<(Car,Car)> với luồng thứ hai bằng cách nào đó được tạo ra bởi kênh thứ nhất (điều này nghe có vẻ khủng khiếp và ở đây tôi không có ý tưởng, cách này sẽ trông như thế nào).

Có cách nào tốt đẹp để làm điều này với luồng hoặc chúng tôi bị kẹt vào vòng lặp for không?

+3

Vòng lặp for is not ridiculous. Trên thực tế, đây có lẽ là mã sạch hơn bạn sẽ có thể viết cho điều này. Bạn luôn có thể sử dụng Luồng trên các chỉ mục nhưng đó là nó. – Tunaki

+0

@Tunaki Tôi đã nói, các luồng sẽ trông vô lý, không phải là vòng lặp. Cho đến nay tôi cũng gắn bó với vòng lặp vì những lý do rõ ràng. Tôi chỉ tự hỏi, nếu có một khả năng tốt đẹp để đạt được điều này cũng với các dòng. Chỉnh sửa, bạn có thể hiểu rằng một phần sai, tôi xóa nó. – ctst

+0

Ah Tôi hiểu lầm xin lỗi. – Tunaki

Trả lời

3

Gắn bó với vòng lặp for sẽ không phải là một ý tưởng tồi. API luồng không được thiết kế cho loại yêu cầu này. Bạn có thể tham khảo that answer để có thêm thông tin chi tiết.

Tuy nhiên, cách đơn giản để thực hiện việc này bằng API luồng sẽ là sử dụng Luồng trên các chỉ mục trong danh sách của bạn, giả sử bạn có quyền truy cập ngẫu nhiên.

IntStream.range(0, autobahn.size() - 1) 
     .filter(i -> autobahn.get(i).speed > autobahn.get(i+1).speed) 
     .forEach(i -> autobahn.get(i).honk()); 

Lưu ý rằng điều này rất giống với for vòng lặp.

+2

Resembles vòng lặp 'for' nhưng làm cho xử lý song song có thể. –

+0

Như @ ErickG.Hagstrom đã đề cập, điều này có thể có hiệu suất tốt hơn. Bằng cách nào đó tôi chỉ cần giám sát giải pháp thanh lịch và đơn giản này.Ngoài ra liên kết có một số câu trả lời thú vị cho khía cạnh này. Tôi không chắc chắn, nếu câu trả lời này là thực sự nhanh hơn trong trường hợp sử dụng của tôi (LinkedList), nhưng nó chắc chắn đáp ứng câu hỏi của tôi. – ctst

+1

@ctst Nếu bạn có một 'LinkedList', điều này chắc chắn không phải là câu trả lời hay, hiệu quả. Một LinkedList không có quyền truy cập ngẫu nhiên để truy cập theo chỉ mục là thảm họa. Trong trường hợp đó, sẽ tốt hơn nếu trước tiên chuyển đổi thành một 'ArrayList', hoặc sử dụng vòng lặp for với một trình lặp. – Tunaki

0

gì về việc sử dụng IntStream thay vì một vòng lặp:

IntStream.range(0, autobahn.size() - 1) 
     .filter(i -> autobahn.get(i).speed < autobahn.get(i + 1).speed) 
     .forEach(i -> autobahn.get(i).honk()); 
1

Sử dụng miễn phí StreamEx thư viện của tôi:

StreamEx.of(autobahn) 
     .pairMap((car, nextCar) -> car.speed < nextCar.speed ? car : null) 
     .nonNull() 
     .forEach(Car::honk); 

Đây phi tiêu chuẩn pairMap hoạt động được sử dụng mà có thể lập bản đồ các cặp liền kề của các yếu tố thành phần tử đơn lẻ. Điều này làm việc cho bất kỳ nguồn luồng nào (không chỉ danh sách được lập chỉ mục truy cập ngẫu nhiên) và có thể được song song khá tốt.

Các vấn đề liên quan