流是Java API的新成員,它容許你以聲明性方式處理數據集合(經過查詢語句來表達,而不是臨時編寫一個實現)。就如今來講,你能夠把它們當作遍歷數據集的高級迭代器。此外,流還能夠透明地並行處理。讓咱們來看一個實例返回低熱量(<400)的菜餚名稱:< p=""> java
Java7版本:
List<Dish> lowCaloricDishes = new ArrayList<>();
// 用累加器篩選元素
for(Dish d: menu){
if(d.getCalories() < 400){
lowCaloricDishes.add(d);
}
}
// 用匿名類對菜餚排序
Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
public int compare(Dish d1, Dish d2){
return Integer.compare(d1.getCalories(), d2.getCalories());
}
});
// 處理排序後的菜名列表
List<String> lowCaloricDishesName = new ArrayList<>();
for(Dish d: lowCaloricDishes){
lowCaloricDishesName.add(d.getName());
}
Java8版本:
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
List<String> lowCaloricDishesName = menu.stream()
.filter(d -> d.getCalories() < 400) // 選出400卡路里如下的菜餚
.sorted(comparing(Dish::getCalories)) // 按照卡路里排序
.map(Dish::getName) // 提取菜餚名稱
.collect(toList()); // 將全部的名稱保存在List中
利用多核架構並行執行,只須要把stream()換成parallelStream()複製代碼
Java 8中的Stream API特性:數據庫
流定義:編程
集合與流之間的差別就在於何時進行計算。集合是一個內存中的數據結構,它包含數據結構中目前全部的值——集合中的每一個元素都得先算出來才能添加到集合中。相比之下,流則是在概念上固定的數據結構(你不能添加或刪除元素),其元素則是按需計算的。集合和流的另外一個關鍵區別在於它們遍歷數據的方式。數組
和迭代器相似,流只能遍歷一次。遍歷完以後,咱們就說這個流已經被消費掉了。如下代碼會拋出一個異常,說流已被消費掉了:數據結構
List<String> title = Arrays.asList(「Java8」,」In」, 「Action」);
Stream<String> s = title.stream();
s.forEach(System.out::println);
s.forEach(System.out::println);
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at com.lujiahao.learnjava8.chapter4.StreamAndCollection.main(StreamAndCollection.java:16)複製代碼
使用Collection接口須要用戶去作迭代(好比用for-each),這稱爲外部迭代。相反,Streams庫使用內部迭代架構
集合:用for-each循環外部迭代
List<String> names = new ArrayList<>();
for(Dish d: menu){
names.add(d.getName());
}
集合:用背後的迭代器作外部迭代
List<String> names = new ArrayList<>();
Iterator<String> iterator = menu.iterator();
while(iterator.hasNext()) {
Dish d = iterator.next();
names.add(d.getName());
}
流:內部迭代
List<String> names = menu.stream()
.map(Dish::getName)
.collect(toList());複製代碼
java.util.stream.Stream中的Stream接口定義了許多操做。它們能夠分爲兩大類。能夠鏈接起來的流操做稱爲中間操做,關閉流的操做稱爲終端操做。中間操做:除非流水線上觸發一個終端操做,不然中間操做不會執行任何處理。終端操做:會從流的流水線生成結果。其結果是任何不是流的值。編程語言
流的使用通常包括三件事:函數式編程
流的流水線背後的理念相似於構建器模式。函數
常見流操做:性能
如下是你應從本章中學到的一些關鍵概念。