Java8-Stream之數值流


在Stream里元素都是對象,那么,當我們操作一個數字流的時候就不得不考慮一個問題,拆箱和裝箱。雖然自動拆箱不需要我們處理,但依舊有隱含的成本在里面。Java8引入了3個原始類型特化流接口來解決這個問題:IntStream,DoubleStream,LongStream, 分別將流中的元素特化為int、long、doub,從而避免了暗含的裝箱成本。每個接口都帶來了進行常用數值歸約的新方法,比如求和sum,求最大值max。此外還有必要時再把他們轉換回對象流的方法。這些特化的原因就是裝箱造成的復雜性--類似int和Integer之間的效率差異。

將對象流映射為數值流

常用方法為mapToInt, mapToDouble, mapToLong,這些方法和map相同,只是它們返回一個特化流,而不是Stream

@Test
public void testToInt() {
    final ArrayList<Dish> dishes = Lists.newArrayList(
            new Dish("pork", false, 800, Type.MEAT),
            new Dish("beef", false, 700, Type.MEAT),
            new Dish("chicken", false, 400, Type.MEAT),
            new Dish("french fries", true, 530, Type.OTHER),
            new Dish("rice", true, 350, Type.OTHER),
            new Dish("season fruit", true, 120, Type.OTHER),
            new Dish("pizza", true, 550, Type.OTHER),
            new Dish("prawns", false, 300, Type.FISH),
            new Dish("salmon", false, 450, Type.FISH)
    );

    IntStream intStream = dishes.stream()
            .mapToInt(Dish::getCalories);
}

將數值流轉回對象流

我們雖然會使用數值流進行計算,但經常需要回歸到對象,那么就需要將int stream裝箱為Integer stream. 可以使用boxed()方法。

Stream<Integer> boxed = intStream.boxed();

默認值OptinalInt

由於數值流經常會有默認值,比如默認為0。數值特化流的終端操作會返回一個OptinalXXX對象而不是數值。

OptionalInt optionalInt = dishes.stream()
                .mapToInt(Dish::getCalories)
                .max();

int max = optionalInt.orElse(1);

生成一個數值范圍流

有時候需要生成一個數值范圍,比如1到30. 可以使用for循環,也可以直接使用數值流。

創建一個包含兩端的數值流,比如1到10,包含10:

IntStream intStream = IntStream.rangeClosed(1, 10);

創建一個不包含結尾的數值流,比如1到9:

IntStream range = IntStream.range(1, 9);

測試demo: https://github.com/Ryan-Miao/someTest/blob/master/src/main/java/com/test/java8/streams/NumStreamExample.java

以上出自《Java8 In Action》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM