2016-05-20 15 views
5

Tôi đã tự hỏi liệu có cách nào để đạt được điều sau đây trong vòng một lần lặp qua mảng không. Chỉ cần có hai kết quả khác nhau ngoài luồng.Tính tổng và tổng bình phương cùng một lúc với Luồng

double sum = Arrays.stream(doubles).sum(); 
double sumOfSquares = Arrays.stream(doubles).map(d -> d * d).sum(); 
+3

Nếu bạn thấy mình cần nhiều loại thống kê này thì phân lớp [DoubleSummaryStatistics] (https://docs.oracle.com/javase/8/docs/api/java/util/DoubleSummaryStatistics.html) có thể có ý nghĩa. – the8472

+2

Câu hỏi liên quan (sử dụng ý tưởng từ @ the8472) http://stackoverflow.com/questions/36263352/java-streams-standard-deviation – Tunaki

+6

Cách tiếp cận được đề nghị ở đây thực sự là phân lớp 'DoubleSummaryStatistics'. Điều đó nói, hãy cẩn thận. Chúng tôi xem xét bao gồm tổng bình phương trong DSS, nhưng không chọn vì (a) tính toán nhiều hơn mà nhiều người dùng muốn, nhưng quan trọng hơn (b) rất dễ gặp rắc rối bằng số với phương sai tính toán dấu phẩy động bằng tổng các ô vuông. (Squaring làm cho các số lớn lớn hơn và nhỏ hơn, dẫn đến nguy cơ mất dữ liệu khi bạn thêm chúng.) Xem Knuth AOCP, vol 2, sec 4.2.2 để biết thêm chi tiết. –

Trả lời

13

Vâng, bạn có thể với một nhà sưu tập tùy chỉnh, ví dụ:

double[] res = 
    Arrays.stream(doubles) 
      .collect(() -> new double[2], 
        (arr, e) -> {arr[0]+=e; arr[1]+=e*e;}, 
        (arr1, arr2) -> {arr1[0]+=arr2[0]; arr1[1]+=arr2[1];}); 

double sum = res[0]; 
double sumOfSquares = res[1]; 

nhưng bạn không đạt được nhiều khả năng đọc theo ý kiến ​​của tôi, vì vậy tôi sẽ gắn bó với các giải pháp vượt qua nhiều (hoặc có thể chỉ cần sử dụng for-loop trong trường hợp này).

+0

Cảm ơn rất nhiều! Tôi vẫn đang học các luồng, vì vậy nó thực sự hữu ích. – HectorBarbossa

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