2013-04-03 24 views
10

Tại sao lớp JDK8 Stream mới chỉ chứa reduce phương pháp sau đây:Strange "giảm" nhóm phương pháp trong JDK8 thư viện hoạt động thu gom số lượng lớn

T reduce(BinaryOperator<T> reducer) 
T reduce(T identity, BinaryOperator<T> reducer) 
U reduce(U identity, BiFunction<U, ? super T, U> reducer, 
    BinaryOperator<U> combiner) 

nhưng không phải là một phương pháp rõ ràng tương ứng với reduce/fold chức năng tìm thấy trong các ngôn ngữ khác (ví dụ: Haskell foldl :: (a -> b -> a) -> a -> [b] -> a) và có thể trông giống như sau:

U reduce(U identity, BiFunction<U, ? super T, U> reducer) 

?

Thay vào đó, có một phương pháp tương tự có thêm đối số combiner. Tôi thậm chí không chắc chắn làm thế nào để sử dụng nó vì các tài liệu API tôi liên kết đến ở trên không sử dụng đối số này trong ví dụ, nó chỉ đề cập đến các thuộc tính cần thiết của nó.

Tại sao các phương thức JDK8 được thực hiện như thế này và làm cách nào để mô phỏng hành vi tiêu chuẩn fold với chúng?

Trả lời

10

Các hoạt động song song dữ liệu giống như reduce đóng vai trò như các hoạt động tổng hợp giá trị chung trên tập dữ liệu (ví dụ: một mảng các phần tử). Bạn có thể sử dụng chúng để thực hiện, ví dụ, tổng.

Thứ tự mà các giá trị của tập dữ liệu được kết hợp với nhau (ví dụ tổng hợp) không được xác định, vì vậy họ không tương ứng với foldl tìm thấy trong Haskell hoặc reduceLeft/foldLeft tìm thấy trong Scala.

Đối số bổ sung combiner trong dòng thứ ba được sử dụng khi loại kết quả của tập hợp khác với loại phần tử của bạn. Trong những trường hợp này, bạn phải chỉ định cách kết hợp hai kết quả lại với nhau. Cho phép nói rằng bạn muốn thực hiện tổng số nguyên âm trong chuỗi bằng cách sử dụng lần giảm thứ ba. Các yếu tố dữ liệu là ký tự và reducer quy định cụ thể như thế nào một nhân vật và số lượng hiện tại được kết hợp:

(Integer count, Character c) -> if (isVowel(c)) count + 1 else count 

các bộ kết hợp sẽ chỉ là một tổng:

(Integer count1, Integer count2) -> count1 + count2 

Scala Parallel Collections, ví dụ, có những for a while now (tìm kiếm aggregate).

+2

Câu trả lời rất hữu ích, cảm ơn, nhưng tôi phải suy nghĩ trong vài phút để xem kết nối giữa sự hiện diện của bộ kết hợp và tính độc lập của đơn đặt hàng (và do đó là sự thân thiện song song) của phiên bản thứ ba. Để đánh vần nó cho mọi người chậm như tôi: không có cách nào để kết hợp hai 'U', bộ giảm tốc chỉ có 'BiFunction 'để làm việc với, điều đó có nghĩa là nó chỉ có thể xử lý một' T' tại một thời điểm, có hiệu quả tuần tự hóa hoạt động. –

+1

Chính xác - Tôi có thể đã có một chút vẫy tay, được giải thích rất độc đáo. – axel22

+0

Cảm ơn cả hai rất nhiều, bây giờ nó đã trở nên rõ ràng hơn nhiều. Tuy nhiên, tôi vẫn không hiểu làm thế nào tôi có thể mô phỏng hành vi gấp chuẩn. Nói cách khác, tôi đoán có thể tôi có bộ giảm tốc được xác định rõ ràng, nhưng không có bộ kết hợp được xác định rõ ràng (hoặc viết nó là khó khăn/bất tiện), và tôi không nhớ có 'giảm' làm việc tuần tự. Tôi nên làm cái gì sau đó? –

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