Java8 新特性Stream流

說明:本案例來自 《Java8 實戰》書籍,有需要的朋友到本書的朋友到相關網站購買

電子書的話本人百度網盤提供PDF:(鏈接失效請留言)

鏈接: https://pan.baidu.com/s/1rOji5sj0cOADI2l5dMuHqA 提取碼: efxc

解決下載限速問題查看這篇文章:https://blog.csdn.net/love_moon821/article/details/88896665

流是什麼?

流是Java API的新成員,它允許你以聲明性方式處理數據集合(通過查詢語句來表達,而不
是臨時編寫一個實現)。
流的使用一般包括三件事:

  •  一個數據源(如集合)來執行一個查詢;
  •  一箇中間操作鏈,形成一條流的流水線;
  •  一個終端操作,執行流水線,並能生成結果。
     

下面兩段代碼都是用來返回低熱量的菜餚名稱的,並按照卡路里排序,一個是用Java 7寫的,另一個是用Java 8的流寫的。
 

//之前(Java 7):
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());//處 理 排 序 後的菜名列表
}

在這段代碼中,你用了一個“垃圾變量” lowCaloricDishes。它唯一的作用就是作爲一次性的中間容器。

在Java 8中,實現的細節被放在它本該歸屬的庫裏了。
 

//之後(Java 8):
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
List<String> lowCaloricDishesName =
menu.stream()
.filter(d -> d.getCalories() < 400)//選出400卡路里以下的菜餚(這也Java8 的一個新特性, Lambda表達式)
.sorted(comparing(Dish::getCalories))//按照按照卡路里排序
.map(Dish::getName)//提取菜餚名稱
.collect(toList());//將所有名稱保存在一個新的List中
//爲了利用多核架構並行執行這段代碼,你只需要把stream()換成parallelStream():
List<String> lowCaloricDishesName =
menu.parallelStream()
.filter(d -> d.getCalories() < 400)
.sorted(comparing(Dishes::getCalories))
.map(Dish::getName)
.collect(toList());

你可以把幾個基礎操作鏈接起來,來表達複雜的數據處理流水線(在filter後面接上sorted、 map和collect操作,如圖4-1所示),同時保持代碼清晰可讀。 filter的結果被傳給了sorted方法,再傳給map方法,最後傳給collect方法。
因爲filter、 sorted、 map和collect等操作是與具體線程模型無關的高層次構件,所以
它們的內部實現可以是單線程的,也可能透明地充分利用你的多核架構!在實踐中,這意味着你
用不着爲了讓某些數據處理任務並行而去操心線程和鎖了, Stream API都替你做好了!

//Dish類的定義是:
public class Dish {
private final String name;
private final boolean vegetarian;
private final int calories;
private final Type type;
public Dish(String name, boolean vegetarian, int calories, Type type) {
this.name = name;
this.vegetarian = vegetarian;
this.calories = calories;
this.type = type;
}
public String getName() {
return name;
}
public boolean isVegetarian() {
return vegetarian;
}
public int getCalories() {
return calories;
}
public Type getType() {
return type;
}
@Override
public String toString() {
return name;
}
public enum Type { MEAT, FISH, OTHER }
}

//這是一張菜餚

List<Dish> menu = Arrays.asList(
new Dish("pork", false, 800, Dish.Type.MEAT),
new Dish("beef", false, 700, Dish.Type.MEAT),
new Dish("chicken", false, 400, Dish.Type.MEAT),
new Dish("french fries", true, 530, Dish.Type.OTHER),
new Dish("rice", true, 350, Dish.Type.OTHER),
new Dish("season fruit", true, 120, Dish.Type.OTHER),
new Dish("pizza", true, 550, Dish.Type.OTHER),
new Dish("prawns", false, 300, Dish.Type.FISH),
new Dish("salmon", false, 450, Dish.Type.FISH) );
 

實例:獲取菜餚裏卡路里最高的前三個的名稱> 300 的菜餚的名稱 

List<String> threeHighCaloricDishNames =
        //建立操作流水線
        menu.stream()
            //按照卡路里排序(升序), 加上reversed()逆序, 可以理解爲降序吧
            .sorted(Comparator.comparing(Dish::getCalories).reversed())
            //篩選熱量高與300的菜餚(這也是Java8的一個新特性 Lambda表達式)
            .filter(d -> d.getCalories() > 300)
            //獲取菜名(Lambda表達式)    
            .map(Dish::getName)
            //只選擇前三個(截斷流,使其元素不超過給定數量)
            .limit(3)
            //將結果保留在另一個新的list中(將流轉換爲其他形式)   
            .collect(Collectors.toList());

結果是:[pork, beef, pizza]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章