第5篇 stream ---數值流
阿新 • • 發佈:2018-12-16
** * Java 8引入了三個原始型別特化流介面來解決這個問題:IntStream、DoubleStream和 * LongStream,分別將流中的元素特化為int、long和double,從而避免了暗含的裝箱成本。每 * 個介面都帶來了進行常用數值歸約的新方法,比如對數值流求和的sum,找到最大元素的max。 * 此外還有在必要時再把它們轉換回物件流的方法。要記住的是,這些特化的原因並不在於流的復 * 雜性,而是裝箱造成的複雜性——即類似int和Integer之間的效率差異 */ public class PrimitiveTypeDemo { public static void main(String[] args) { List<Dish> menues = Arrays.asList(new Dish("rice", true, 10000, Dish.Type.FISH), new Dish("meat", false, 20000, Dish.Type.FISH), new Dish("dog", true, 30000, Dish.Type.FISH)); test01(menues); } /** * 1. 對映到數值流: * 將流轉換為特化版本的常用方法是mapToInt、mapToDouble和mapToLong。這些方法和前 * 面說的map方法的工作方式一樣,只是它們返回的是一個特化流,而不是Stream<T>。例如,你 * 可以像下面這樣用mapToInt對menu中的卡路里求和: * 這裡,mapToInt會從每道菜中提取熱量(用一個Integer表示),並返回一個IntStream * (而不是一個Stream<Integer>)。然後你就可以呼叫IntStream介面中定義的sum方法,對卡 * 路里求和了!請注意,如果流是空的,sum預設返回0。IntStream還支援其他的方便方法,如 * max、min、average等。 */ public static void test01(List<Dish> menues) { int sum = menues.stream().mapToInt(Dish::getCalories).sum(); System.out.println(sum); } /** * 轉換回物件流: * 同樣,一旦有了數值流,你可能會想把它轉換回非特化流。例如,IntStream上的操作只能 * 產生原始整數: IntStream 的 map 操作接受的 Lambda 必須接受 int 並返回 int (一個 * IntUnaryOperator)。但是你可能想要生成另一類值,比如Dish。為此,你需要訪問Stream * 介面中定義的那些更廣義的操作。要把原始流轉換成一般流(每個int都會裝箱成一個 * Integer),可以使用boxed方法,如下所示: * @param menues */ public static void test02(List<Dish> menues) { IntStream intStream = menues.stream().mapToInt(Dish::getCalories); Stream<Integer> boxed = intStream.boxed(); } /** * 預設值OptionalInt: * 求和的那個例子很容易,因為它有一個預設值:0。但是,如果你要計算IntStream中的最 * 大元素,就得換個法子了,因為0是錯誤的結果。如何區分沒有元素的流和最大值真的是0的流呢? * 前面我們介紹了Optional類,這是一個可以表示值存在或不存在的容器。Optional可以用 * Integer、String等參考型別來引數化。對於三種原始流特化,也分別有一個Optional原始類 * 型特化版本:OptionalInt、OptionalDouble和OptionalLong; * 例如,要找到IntStream中的最大元素,可以呼叫max方法,它會返回一個OptionalInt: * @param menues */ public static void test03(List<Dish> menues) { OptionalInt max = menues.stream().mapToInt(Dish::getCalories).max(); if(max.isPresent()){ System.out.println("有最大值"+max.getAsInt()); }else{ int defaultValue = max.orElse(1); System.out.println("沒有最大值,採用預設的最大值"+defaultValue); } } }