流是 從 源生成的 元素序列。java
流是 從支持數據處理操做的 源生成的 元素序列。數據結構
數據處理操做 如filter、map、reduce、find、match、sort等。優化
流操做有兩個重要的特色:code
粗略地說,集合與流之間的差別就在於何時進行計算。集合是一個內存中的數據結構,它包含數據結構中目前全部的值——集合中的每一個元素都得先算出來才能添加到集合中。(內存
相比之下,流則是在概念上固定的數據結構(你不能添加或刪除元素),其元素則是按需計算的。get
有點抽象類比爲生產手機的流水線吧:集合是一堆生產好的手機,想放進去一個手機,那麼這個手機必須生產好的。流是在流水線上的還未生產好的手機,流水線上不能拿走一個,也不能隨意放上去一個,流水線上會有一些操做。it
流只能遍歷一遍!io
List<String> title = Arrays.asList("Java8", "In", "Action"); Stream<String> s = title.stream(); s.forEach(System.out::println); //成功遍歷 s.forEach(System.out::println);//java.lang.IllegalStateException:流已被操做或關閉
集合:外部迭代class
流:內部迭代 內部迭代時,項目能夠透明地並行處理,或者用更優化的順序進行處理。stream
List<String> names = menu.stream() .filter(d -> d.getCalories() > 300) .map(Dish::getName) .limit(3) .collect(toList());
你能夠看到兩類操做:
filter、map和limit能夠連成一條流水線;
collect觸發流水線執行並關閉它。
中間操做返回的仍是流,例如上面代碼的filter、map。除非流水線上觸發一個終端操做,不然中間操做不會執行任何處理——它們很懶。
利用流的延遲性質進行的優化:
終端操做會從流的流水線生成結果。其結果是任何不是流的值。流操做中能夠據此判斷一個操做是中間操做仍是終端操做。
long count = menu.stream() .filter(d -> d.getCalories() > 300) .distinct() .limit(3) .count();//流水線中最後一個操做count返回一個long,這是一個非Stream的值。
流是「從支持數據處理操做的源生成的一系列元素」。
流利用內部迭代:迭代經過filter、map、sorted等操做被抽象掉了。
流操做有兩類:中間操做和終端操做。
filter和map等中間操做會返回一個流,並能夠連接在一塊兒。能夠用它們來設置一條流水線,但並不會生成任何結果。
forEach和count等終端操做會返回一個非流的值,並處理流水線以返回結果。
流中的元素是按需計算的。