java8 學習之路之lambda


 前言

  目前我們知道java的版本已經發布到12了,之前的項目用的是JDK1.7,聽說JDK1.8的改動相對來說大一些,因此抽空學學JDK1.8的一些新特性。本人也是通過閱讀Java8實戰這本書做一些小的總結,方便以后鞏固,同時也為想學習Java1.8的人提供一些思路望大家多多包涵,有不對的地方請提出了我們一起學習。想要Java8實戰這本書電子版的小伙伴可以留言告我可以發給你呦!

 演變過程

  這里我們通過一個簡單的故事來引出神奇的Lambda。這里首先有一個蘋果的實例,其包含簡單的屬性:顏色和重量。

 1 public class Apple {
 2     private int weight = 0;
 3     private String color = "";
 4 
 5     public Apple(int weight, String color){
 6         this.weight = weight;
 7         this.color = color;
 8     }
 9     // get/set/toString  
10 }

  首先我們要獲取紅色的蘋果(因為紅色的好吃嘛),這時候我們會定義一個簡單的方法來進行過濾獲取到紅色的蘋果。

 1     /**
 2      * 篩選紅蘋果
 3      * @param inventory
 4      * @return
 5      */
 6     public static List<Apple> filterRedApples(List<Apple> inventory){
 7         List<Apple> result = new ArrayList<>();
 8 
 9         for (Apple apple: inventory){
10             if ("red".equals(apple.getColor())) {
11                 result.add(apple);
12             }
13         }
14 
15         return result;
16     }

  后來由於蘋果收購商有來了,我不管什么蘋果,只要重量大於150g的統統給我裝上車!好辦啦!我們再加個方法來進行過濾就可以了。

    /**
     * 篩選重量大於150的蘋果
     * @param inventory
     * @return
     */
    public static List<Apple> filterHeavyApples(List<Apple> inventory){
        List<Apple> result = new ArrayList<>();

        for (Apple apple: inventory){
            if (apple.getWeight() > 150) {
                result.add(apple);
            }
        }

        return result;
    }

  過了幾天水果商又來了,我們現在想要綠色的蘋果。這時候你可能想到是加一個方法 filterGreenApples 專門過濾綠色蘋果,然而,如果要篩選多種顏色呢?黃色?暗紅色?難道我們要每個新加一個方法嗎?當然不是!我們最開始想到的是吧顏色作為參數傳進去,試着將其抽象化。

 1     public static List<Apple> filterApplesByColor(List<Apple> inventory,
 2                                                   String color) {
 3         List<Apple> result = new ArrayList<Apple>();
 4 
 5         for (Apple apple: inventory){
 6             if ( apple.getColor().equals(color) ) {
 7                 result.add(apple);
 8             }
 9         }
10 
11         return result;
12     }

  同時我們可能想到將獲取重量的方法也進行優化

 1     public static List<Apple> filterApplesByWeight(List<Apple> inventory,
 2                                                    int weight) {
 3         List<Apple> result = new ArrayList<Apple>();
 4 
 5         for (Apple apple : inventory){
 6             if ( apple.getWeight() > weight ){
 7                 result.add(apple);
 8             }
 9         }
10 
11         return result;
12     }

  這時候就很不錯了,可(cao)愛(dan)的水果商又來了讓我們提供一種方式來區分不同的屬性進行過濾。OK! 我們進行優化!

 1     public static List<Apple> filterApples(List<Apple> inventory, String color,
 2                                            int weight, boolean flag) {
 3         List<Apple> result = new ArrayList<Apple>();
 4 
 5         for (Apple apple: inventory){
 6             if ( (flag && apple.getColor().equals(color)) ||
 7                     (!flag && apple.getWeight() > weight) ){
 8                 result.add(apple);
 9             }
10         }
11 
12         return result;
13     }

  你會發現這個方法中的flag很難讓人讀懂。而且如果水果商想要再根據不同的屬性進行過濾呢?比如產地、形狀,那么這個方案就不能滿足我們的需求了。

   那么我們如何應對這種多變的需求呢?讓我們來定義一個接口對蘋果過濾器進行建模。

1 public interface AppleFilter {
2     boolean test(Apple apple);
3 }

  我們定義一個接口對蘋果進行過濾,你可以定義多個實現類來選擇不同的標准。

 1 public class AppleGreenColorFiler implements AppleFilter {
 2     @Override
 3     public boolean test(Apple apple) {
 4         return "green".equals(apple.getColor());
 5     }
 6 }
 7 
 8 public class AppleHeavyWeightFilter implements AppleFilter {
 9     @Override
10     public boolean test(Apple apple){
11         return apple.getWeight() > 150;
12     }
13 }

  這種實現方式類似與策略模式,我們可以將這種行為的實現作為一個參數傳遞進去。

 1     public static  List<Apple> filterApples(List<Apple> inventory, AppleFilter appleFilter) {
 2         List<Apple> result = new ArrayList<Apple>();
 3 
 4         for (Apple apple : inventory) {
 5             if(appleFilter.test(apple)) {
 6                 result.add(apple);
 7             }
 8         }
 9 
10         return result;
11     }

  這時候我們會發現我們的代碼靈活很多了,可以應對水果商的各種需求了。而過濾的主要業務我們是在其實現類中進行定義的。我們甚至可以同時獲取重量大於150並且是紅色的蘋果。

1 public class AppleRedAndHeavyFilter implements AppleFilter {
2     @Override
3     public boolean test(Apple apple) {
4         return "red".equals(apple.getColor()) && apple.getWeight() > 150;
5     }
6 }

  這時候我們發現我們可以使用匿名內部類做代碼的優化。並不需要每次都創建其實現類來完成。

1 List<Apple> redApples = filterApples(inventory, new AppleFilter() {
2     @Override
3     public boolean test(Apple apple) {
4         return "red".equals(apple.getColor());
5     }
6 });

  那么在Java8中我們怎么做呢?看好啦!

1 List<Apple> redApples = filterApples(inventory, (Apple apple) -> "red".equals(apple.getColor()));

  這樣的代碼即簡潔又容易讀懂。

其他例子

  其實這樣的寫法可以針對很多地方,例如我們在使用Comparator對集合中的數據進行排序的時候,再比如使用Runnable創建線程的時候。這里就不再舉例了,希望大家自己在下面試試這幾種方式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM