2016-05-20 70 views
5

我想知道是否有任何方法可以在數組的單個迭代內實現以下功能。簡單地說,有兩種不同的結果。與Streams同時計算總和和平方和

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

如果您發現自己需要大量這類統計信息,那麼對[DoubleSummaryStatistics]進行子類化(https://docs.oracle.com/javase/8/docs/api/java/util/DoubleSummaryStatistics.html)可能會有意義。 – the8472

+2

相關問題(使用從@ the8472的想法)http://stackoverflow.com/questions/36263352/java-streams-standard-deviation – Tunaki

+6

這裏推薦的方法確實是子類'DoubleSummaryStatistics'。這就是說,小心點。我們考慮在DSS中包括平方和,但並未選擇,因爲(a)許多用戶需要更多的計算,但更重要的是(b)通過求和計算浮點計算方差很容易導致數值問題的平方。 (Squaring使大數字變小,小數字變小,導致添加時丟失數據的風險。)有關更多詳細信息,請參閱Knuth AOCP,第2卷第4.2.2節。 –

回答

13

嗯,你可以使用自定義的收藏家,例如:

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]; 

但你不要在我看來獲得太多的可讀性,所以我會用多遍液粘(或可能只是在這種情況下使用for循環)。

+0

非常感謝!我還在學習流媒體,所以這真的很有幫助。 – HectorBarbossa