java8學習:引入stream
內容來自《 java8實戰 》,本篇文章內容均為非盈利,旨為方便自己查詢、總結備份、開源分享。如有侵權請告知,馬上刪除。
書籍購買地址:java8實戰
- 這一篇內容要講的是流,關於流的概念,流的內部迭代跟外部迭代的區別之類的偏概念性的問題,下一篇在細講流到底是什麼用
- 那麼說到流,我們自然就會想到水,這就涉及到水源頭是哪裡,水怎麼流過來的,水會被我們的桶收集起來,還是說用水杯收集起來,那麼問題就一下子出現了三個
-
流的源頭是哪裡
- 流的源頭包括集合,陣列或者一些輸入輸出資源,但是需要注意的是,從有序集合生成流時會保持原有的資料,從列表生成的流,其元素資料與列表一致
-
流是怎麼個處理過程
- 這其實就要設計到用到了具體的api了,下面會說到
-
流的收集
- 無非就是收整合集合等一些等儲存資料的資料結構中
-
流和集合作對比
- 一點很清楚的就是,流是來做計算的,而集合是用來儲存的,這個應該很容易理解
- 還有一個就是:我們需要看一部電影,那麼無非就是兩種線上看和下載下來看,那麼線上看就屬於流模式,而整個資源下載下來看就屬於集合模式了,所以從簡單的說集合與流之間的差異就在與什麼時候計算。集合是一個記憶體中的資料結構,它包含了所有值,就比如我們使用的list,不管新增還是刪除他總是在記憶體中操作的,並且它是每個元素先計算出來再新增到集合的,而流呢?他就像我們線上看電影一樣,不需載入全部的資料,劇情無聊快進的時候,流的處理方式就是載入你點選的時間點之後的幾幀來供你觀看,這就是他們的區別
-
好了扯了一大堆概念,讓我們來看看集合和流處理資料的方式
- 我們利用下面這個類的結構來編寫程式碼
@Data public class Dish { private final String name; private final boolean vegetarian; //是否是素菜 private final int calories; //卡路里 private final Type type; private enum Type{ MEAT,FISH,OTHER; } public Dish(String name, boolean vegetarian, int calories, Type type) { this.name = name; this.vegetarian = vegetarian; this.calories = calories; this.type = type; } }
- 好了讓我們建立一個集合
List<Dish> menu = Arrays.asList( new Dish("apple",true,50, Dish.Type.OTHER), new Dish("chicken",false,350, Dish.Type.MEAT), new Dish("rich",true,150, Dish.Type.OTHER), new Dish("pizza",true,350, Dish.Type.OTHER), new Dish("fish",false,250, Dish.Type.FISH), new Dish("orange",true,70, Dish.Type.OTHER), new Dish("banana",true,60, Dish.Type.OTHER));
- 集合操作:找出卡路里最低排名的前三位
@Test public void test() throws Exception { menu.sort(new Comparator<Dish>() { @Override public int compare(Dish o1, Dish o2) { return o1.getCalories() - o2.getCalories(); } }); for (int i = 0; i < 3; i++) { System.out.println(menu.get(i)); } }
- 流操作:找出卡路里最低排名的前三位
@Test public void test() throws Exception { List<Dish> collect = menu .stream() .sorted(Comparator.comparing(Dish::getCalories)) .limit(3) .collect(Collectors.toList()); for (Dish dish : collect) { System.out.println(dish); } }
- 觀察上面兩種,肯定是流操作比較好一些,因為它操作的每一步都很清楚的告訴開發者他的流在幹什麼,如上就是流和集合的一個簡單對比
-
如上其實也反映了兩個:內部迭代和外部迭代,流就屬於內部迭代,集合的操作的方法就是外部迭代
- 內部迭代就是按照我們的意思,類似SQL似的查詢操作,比如取前三啊那就是limit(3),然後他會根據你的查詢條件自動的去遍歷你的集合,這樣就省去自己去一步步的寫邏輯了
- 外部迭代自己理解的就是需要開發者手動編寫遍歷邏輯
- 那麼流是一個一次性的,所以我們看如下
Stream<Dish> limit = menu.stream() .sorted(Comparator.comparing(Dish::getCalories)) .limit(3); List<Dish> collect1 = limit.collect(Collectors.toList()); //IllegalStateException: stream has already been operated upon or closed List<Dish> collect2 = limit.collect(Collectors.toList());
-
- 上面就充分說明了,流只能遍歷一次。當遍歷一次之後這個流就被消費掉了,如果重新需要,那麼需要從源頭那再獲取個stream
- 我們看下面的程式碼
Stream<Dish> limit = menu.stream()
.sorted(Comparator.comparing(Dish::getCalories))
.limit(3);
System.out.println(limit);//java.util.stream.SliceOps$1@436e852b
List<Dish> collect1 = limit.collect(Collectors.toList()); //結果
- 這段程式碼就可以說明了,流是一種類似懶載入模式的,只有觸發終端操作,那麼這個流才會開始啟動遍歷資料,如上我們一直到limit(3)這都是流的中間操作,流的中間操作是不會產生資料的,只有出發了collect方法這個終端方法才會開始流的遍歷工作,當然中間操作不止limit,sorted,終端操作也不止collect,這一篇只是簡單的引入一下流而已,下一篇內容將會講stream的使用
好了這一篇內容就介紹到這,主要介紹了流的概念,流和集合的區別,內外迭代和流的中間操作以及終端操作,還有重要的一點就是流是一次性的
相關文章
- java8原始碼學習-java.util.stream:我Stream誕生啦Java原始碼
- Java8——Stream流Java
- 《Java8實戰》-第四章讀書筆記(引入流Stream)Java筆記
- Java8 Lambda 之 Collection StreamJava
- Java8的Stream API使用JavaAPI
- Java8新特性--Stream APIJavaAPI
- java8新特性stream流Java
- 淺析Java8 Stream原理Java
- Java8 Stream常用API整理JavaAPI
- Java8中的Stream APIJavaAPI
- Java8新特性系列(Stream)Java
- Java8 Stream的總結Java
- java8 Stream APi 入門JavaAPI
- 13. 尚矽谷_Java8新特性_Stream API 練習JavaAPI
- oracle stream學習(一)Oracle
- java8 Stream流操作介紹Java
- Java8 - Stream API快速入門JavaAPI
- 我是如何理解Java8 StreamJava
- Java8之Stream常用操作方式Java
- Java8 Stream流的合併Java
- Java8 Stream完全使用指南Java
- Java8學習之路-Java8的發展Java
- 學習Java8系列-LambdaJava
- java8實戰學習Java
- java8新特性學習Java
- JAVA8-stream學習Java
- java的Stream流學習Java
- Java8 Lambda表示式與Stream API (二): Stream API的使用JavaAPI
- Java8中的 lambda 和Stream APIJavaAPI
- Java8新特性探索之Stream介面Java
- list轉map,使用java8,stream流Java
- JDK 1.8 新特性學習(Stream)JDK
- Java學習之流Stream理解(一)Java
- Scala學習(七)---包和引入
- Java8之Stream-函式式介面Java函式
- Java8之Stream流(三)縮減操作Java
- Java8 新特性 —— Stream 流式程式設計Java程式設計
- Java8中Stream 的一些用法Java