1. 程式人生 > >Java8-轉為流為基本資料型別求最大值、最小值、平均值、求和、計數

Java8-轉為流為基本資料型別求最大值、最小值、平均值、求和、計數

基本資料型別在高階函式中的運用

眾所周知,在Java中使用基本資料型別的效能和產效率遠高於包裝型別。由於裝箱型別是物件,因此在記憶體中存在額外開銷。比如,整型在記憶體中佔用4 位元組,整型物件卻要佔用 16 位元組。這一情況在陣列上更加嚴重,整型陣列中的每個元素只佔用基本型別的記憶體,而整型物件陣列中,每個元素都是記憶體中的一個指標,指向 Java堆中的某個物件。在最壞的情況下,同樣大小的陣列, Integer[] 要比 int[] 多佔用 6 倍記憶體。

將基本型別轉換為裝箱型別,稱為裝箱,反之則稱為拆箱,兩者都需要額外的計算開銷。對於需要大量數值運算的演算法來說,裝箱和拆箱的計算開銷,以及裝箱型別佔用的額外記憶體,會明顯減緩程式的執行速度。

為了減小這些效能開銷, Stream 類的某些方法對基本型別和裝箱型別做了區分。Stream中的高階函式 mapToLong 和其他類似函式即為該方面的一個嘗試。在 Java 8 中,僅對整型、長整型和雙浮點型做了特殊處理,因為它們在數值計算中用得最多,特殊處理後的系統性能提升效果最明顯。

計算最大值、最小值、平均值、求和、計數統計

使用 mapToInt、mapToLong、mapToDouble 等高階函式後,得到一個基於基本資料型別的流。針對這樣的流,Java提供了一個摘要統計的功能(對應的類有:IntSummaryStatistics、LongSummaryStatistics 和 DoubleSummaryStatistics),如下程式碼所示:

/**
 * 執行入口
 *
 * @param args 執行引數
 */
public static void main(String[] args) {
    toInt();
    toLong();
    toDouble();
}

private static void toInt() {
    IntSummaryStatistics statistics = Stream.of(1L, 2L, 3L, 4L).mapToInt(Long::intValue).summaryStatistics();
    System.out.println("最大值:" + statistics.
getMax()); System.out.println("最小值:" + statistics.getMin()); System.out.println("平均值:" + statistics.getAverage()); System.out.println("求和:" + statistics.getSum()); System.out.println("計數:" + statistics.getCount()); } private static void toLong() { LongSummaryStatistics statistics = Stream.of(1L, 2L, 3L, 4000000000000000000L).mapToLong(Long::longValue).summaryStatistics(); System.out.println("最大值:" + statistics.getMax()); System.out.println("最小值:" + statistics.getMin()); System.out.println("平均值:" + statistics.getAverage()); System.out.println("求和:" + statistics.getSum()); System.out.println("計數:" + statistics.getCount()); } private static void toDouble() { DoubleSummaryStatistics statistics = Stream.of(1, 2, 3.0, 5.2).mapToDouble(Number::doubleValue).summaryStatistics(); System.out.println("最大值:" + statistics.getMax()); System.out.println("最小值:" + statistics.getMin()); System.out.println("平均值:" + statistics.getAverage()); System.out.println("求和:" + statistics.getSum()); System.out.println("計數:" + statistics.getCount()); }