簡體   English   中英

mapToDouble()是否真的需要將List <Double>與Java 8流相加?

[英]Is mapToDouble() really necessary for summing a List<Double> with Java 8 streams?

據我所知,使用Java 8流對List<Double>求和的方法是這樣的:

List<Double> vals = . . . ;
double sum = vals.stream().mapToDouble(Double::doubleValue).sum();

對我來說, mapToDouble(Double::doubleValue)似乎有點誇張 - 只是那種lambdas和溪流應該免除的樣板“儀式”。

最佳實踐告訴我們更喜歡List實例而不是數組,但是對於這種求和,數組似乎更清晰:

double[] vals = . . . ;
double sum = Arrays.stream(vals).sum();

當然,人們可以做到這一點:

List<Double> vals = . . . ;
double sum = vals.stream().reduce(0.0, (i,j) -> i+j);

但是reduce(....)sum()長得多。

我知道這與流需要圍繞Java的非對象原語進行改造的方式有關,但是,我在這里遺漏了一些東西嗎? 有沒有辦法擠壓自動裝箱以縮短它? 或者這僅僅是當前最先進的技術?


更新 - 答案摘要

以下是答案的摘要。 雖然我在這里有一個摘要,但我敦促讀者自己仔細閱讀答案。

@dasblinkenlight解釋說,由於Java歷史上的進一步決策,特別是在實現泛型的方式以及它們與非對象原語的關系中,因此總是需要某種拆箱。 他指出,理論上編譯器可以直接進行拆箱並允許使用簡短的代碼,但這還沒有實現。

@Holger展示了一個非常接近我所詢問的表現力的解決方案:

double sum = vals.stream().reduce(0.0, Double::sum);

我不知道新的靜態Double.sum()方法。 添加1.8,似乎是出於我描述的目的。 我還找到了Double.min()Double.max() 展望未來,我肯定會在List<Double>上使用這個成語進行此類操作。

有沒有辦法擠壓自動裝箱以縮短它?

就在這里。 你可以簡單地寫:

double sum = vals.stream().mapToDouble(d->d).sum();

這使得取消裝箱是隱含的,但當然不會增加效率。

由於List 裝箱,因此拆箱是不可避免的。 另一種方法是:

double sum = vals.stream().reduce(0.0, Double::sum);

它不會執行mapToDouble但仍允許將代碼讀作“... sum”。

對我來說, mapToDouble(Double::doubleValue)似乎是什么lambda和溪流應該免除。

使用mapToDouble的需要是決定通過類型擦除實現泛型的結果,基本上關閉了在泛型中使用原語的任何可能性。 正是這一決定使得必須創建DoubleStreamIntStreamLongStream類系列 - 以提供基於流的拆箱。

有沒有辦法擠壓自動裝箱以縮短它? 或者這僅僅是當前最先進的技術?

不幸的是,不是在這個時候:雖然理論上編譯器可以理解Stream<Double>可以隱式地轉換為DoubleStream ,但是與原始文件被取消裝箱的方式相同,這還沒有完成。

就基於陣列的解決方案而言,它是三者中效率最高的解決方案。 但是,它不像其他兩個一樣靈活:使用mapToDouble允許您對自定義類的任何屬性求和,而最后一個允許您執行其他類型的聚合。

reduce(....)sum()長得多

我同意,這種方法在可讀性方面比mapToDouble差。

這是另一種方法。 如果您只需要DoubleIntegerLong列表中的sum,average,min,max等,則可以使用其中一個可用的Collectors ,例如:

List<Double> doubles = Arrays.asList(3.14, 5.15, 4.12, 6.);
System.out.println(
        doubles.stream()
                .collect(Collectors.summingDouble(d -> d))
);

會打印18.41

注意,方法名稱是summingDouble ,還有另一個名為summarizingDouble的方法,它返回DoubleSummaryStatistics ,包含所有基本的數學運算結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM