策略模式通過匿名內(nèi)部類進(jìn)行優(yōu)化

行為參數(shù)化

行為參數(shù)化:就是可以幫助你處理頻繁變更的需求的一種軟件開發(fā)模式来氧。

==一言蔽之,它意味著拿出一個(gè)代碼塊驾诈,先把它準(zhǔn)備好確不去執(zhí)行它。這個(gè)代碼塊以后可以被你的程序的其它部分調(diào)用反症,這意味著你可以推遲這塊代碼的執(zhí)行。==

例如:你可以將==代碼塊作為參數(shù)==傳遞給==另一個(gè)方法==砾隅,==稍后再去執(zhí)行它==漠另。這樣這個(gè)方法的行為就是基于代碼被參數(shù)化了漆改。

準(zhǔn)備工作

public class Apple {

    private Integer id;
    private String color;
    private Integer weight;
}

需求1

比如:商家為了賣蘋果俘枫,為了了解自己商品(蘋果)的庫存钟病,需要查找?guī)齑嫠屑t色的蘋果功能。

解決方案如下:

public class LambdaDemo01 {
    public static List<Apple> filterAppleColor(List<Apple> allApples) {
        //1 : 準(zhǔn)備一個(gè)容器用來存儲(chǔ)篩選出紅色蘋果的集合
        List<Apple> resultList = new ArrayList<>();
        //2 : 通過循環(huán)從庫存中allApples去比對(duì)屬于紅色蘋果的數(shù)據(jù)
        for (Apple allApple : allApples) {
            // 3: 比對(duì)紅色的蘋果數(shù)據(jù)
            if(allApple.getColor().equals("紅色")){
                //4 : 然后添加到resultList容器中
                resultList.add(allApple);
            }
        }
        return resultList;
    }


    public static void main(String[] args) {
        // 1暇番、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));

        // 2: 查詢紅色蘋果
        List<Apple> appleList = filterAppleColor(apples);
        appleList.forEach(System.out::println);
    }
}

結(jié)果

Apple{id=1, color='紅色', weight=200}
Apple{id=3, color='紅色', weight=134}

通過上面的第二步嗤放,就是篩選紅色蘋果的所需的條件,現(xiàn)在商家改變了注意了壁酬,他現(xiàn)在還想找到綠色,你該怎么做呢恨课?簡單的辦法就是把代碼復(fù)制一份這個(gè)方法舆乔,把方法的名字改成filterGreenApple即可,然后修改if的條件來匹配綠色

public class LambdaDemo01 {
    public static List<Apple> filterAppleColor(List<Apple> allApples) {
        //1 : 準(zhǔn)備一個(gè)容器用來存儲(chǔ)篩選出紅色蘋果的集合
        List<Apple> resultList = new ArrayList<>();
        //2 : 通過循環(huán)從庫存中allApples去比對(duì)屬于紅色蘋果的數(shù)據(jù)
        for (Apple allApple : allApples) {
            // 3: 比對(duì)紅色的蘋果數(shù)據(jù)
            if(allApple.getColor().equals("紅色")){
                //4 : 然后添加到resultList容器中
                resultList.add(allApple);
            }
        }
        return resultList;
    }
    
    public static List<Apple> filterGreenApple(List<Apple> allApples) {
        //1 : 準(zhǔn)備一個(gè)容器用來存儲(chǔ)篩選出綠色蘋果的集合
        List<Apple> resultList = new ArrayList<>();
        //2 : 通過循環(huán)從庫存中allApples去比對(duì)屬于綠色蘋果的數(shù)據(jù)
        for (Apple allApple : allApples) {
            // 3: 比對(duì)綠色的蘋果數(shù)據(jù)
            if(allApple.getColor().equals("綠色")){
                //4 : 然后添加到resultList容器中
                resultList.add(allApple);
            }
        }
        return resultList;
    }


    public static void main(String[] args) {
        // 1剂公、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));

        // 2: 查詢綠色蘋果
        List<Apple> appleList = filterGreenApple(apples);
        appleList.forEach(System.out::println);
    }
}

然后如果商家想要篩選更多顏色:暗紅色希俩、黃色、淺綠色等纲辽,這樣實(shí)現(xiàn)起來就非常的臃腫和累贅颜武,怎么解決呢璃搜?==行為參數(shù)化==

第一次優(yōu)化:把顏色當(dāng)做參數(shù)

一種做法就是給方法增加一個(gè)參數(shù),把顏色變成參數(shù)鳞上,這樣就能靈活地使用變化了

public class LambdaDemo02 {
    public static List<Apple> filterAppleColor(List<Apple> allApples,String color) {
        //1 : 準(zhǔn)備一個(gè)容器用來存儲(chǔ)篩選出紅色蘋果的集合
        List<Apple> resultList = new ArrayList<>();
        //2 : 通過循環(huán)從庫存中allApples去比對(duì)屬于紅色蘋果的數(shù)據(jù)
        for (Apple allApple : allApples) {
            // 3: 比對(duì)紅色的蘋果數(shù)據(jù)
            if(allApple.getColor().equals(color)){
                //4 : 然后添加到resultList容器中
                resultList.add(allApple);
            }
        }
        return resultList;
    }


    public static void main(String[] args) {
        // 1这吻、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));

        // 2: 查詢紅色蘋果
        List<Apple> appleList = filterAppleColor(apples,"紅色");
        List<Apple> appleList2 = filterAppleColor(apples,"綠色");
        List<Apple> appleList3 = filterAppleColor(apples,"淺紅色");
        System.out.println("--------------紅色------------");
        appleList.forEach(System.out::println);
        System.out.println("--------------綠色------------");
        appleList2.forEach(System.out::println);
        System.out.println("--------------淺紅色------------");
        appleList3.forEach(System.out::println);
    }
}

通過上面,是不是簡單多了

需求2

如果這個(gè)時(shí)候商家又說:要是能區(qū)分重量不一的蘋果該多好呀篙议?

作為軟件工程師的我們唾糯,你可能早就提前做了預(yù)謀,可能商家要改需求鬼贱,可能會(huì)增加重量的過濾移怯,于是你揮揮灑灑的寫下如下可歌可泣的代碼:

public class LambdaDemo02 {

    /**
     * 過濾某顏色蘋果
     *
     * @param appleList
     * @return
     */
    public static List<Apple> filterAppleColor(List<Apple> appleList,String color) {
        List<Apple> resultList = new ArrayList<>();
        for (Apple apple : appleList) {
            if (apple.getColor().equals(color)) {
                resultList.add(apple);
            }
        }
        return resultList;
    }

    /**
     * 過濾重量蘋果
     *
     * @param appleList
     * @return
     */
    public static List<Apple> filterAppleWeigth(List<Apple> appleList,Integer weight) {
        List<Apple> resultList = new ArrayList<>();
        for (Apple apple : appleList) {
            if (apple.getWeight().equals(weight)) {
                resultList.add(apple);
            }
        }
        return resultList;
    }

    public static void main(String[] args) {
        // 1、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));
        // 2这难、過濾紅色蘋果
        List<Apple> resultList1 = filterAppleColor(apples,"紅色");
        System.out.println("==============紅色==================");
        resultList1.forEach(System.out::println);
        // 3舟误、過濾綠色蘋果
        List<Apple> resultList2 = filterAppleColor(apples,"綠色");
        System.out.println("==============綠色==================");
        resultList2.forEach(System.out::println);
        // 4: 過濾重量超過200g的蘋果
        List<Apple> weightList = filterAppleWeigth(apples, 200);
        System.out.println("==============重量200g==================");
        weightList.forEach(System.out::println);
    }
}

這個(gè)時(shí)候,你不由的驚呼道姻乓,我太牛了嵌溢,我實(shí)現(xiàn)了!L侨ā堵腹!

你有沒有發(fā)現(xiàn),這個(gè)代碼確實(shí)比之前的更加高級(jí)了星澳,但是還是沒解決根本性的問題疚顷,如果這個(gè)時(shí)候我還篩選更多的屬性條件,這個(gè)時(shí)候是不是令人有點(diǎn)失望禁偎,因?yàn)槟阌忠煌5闹貜?fù)這個(gè)行為和動(dòng)作腿堤。

如果你想要改變篩選遍歷方式來提升性能,那就得修改所有方法的實(shí)現(xiàn)如暖,而不是改一個(gè)笆檀。從工程的工作量來看,這代價(jià)太大了盒至。

第二天酗洒,商家可能需求就發(fā)生了改變了,我還想找出所有重量超過200g的蘋果枷遂。

如下:

public class LambdaDemo03 {
    /**
     * 需求2:第二天樱衷,商家可能需求就發(fā)生了改變了,我還想找出所有重量超過200g的蘋果酒唉。
     * 真是的需求:查找?guī)齑嫠屑t色的蘋果功能矩桂。
     * @param allApples
     * @return
     */
    public static List<Apple> filterAppleWeight(List<Apple> allApples,int weight) {
        //1 : 準(zhǔn)備一個(gè)容器用來存儲(chǔ)篩選出紅色蘋果的集合
        List<Apple> resultList = new ArrayList<>();
        //2 : 通過循環(huán)從庫存中allApples去比對(duì)屬于紅色蘋果的數(shù)據(jù)
        for (Apple allApple : allApples) {
            // 3: 比對(duì)紅色的蘋果數(shù)據(jù)
            if(allApple.getWeight() > weight){
                //4 : 然后添加到resultList容器中
                resultList.add(allApple);
            }
        }
        return resultList;
    }


    public static void main(String[] args) {
        // 1、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));

        // 2: 查詢蘋果超過200g的數(shù)據(jù)
        List<Apple> appleList = filterAppleWeight(apples,200);
        System.out.println("--------------查詢蘋果超過200g的數(shù)據(jù)------------");
        appleList.forEach(System.out::println);
    }
}

第二次優(yōu)化:一個(gè)方法統(tǒng)一實(shí)現(xiàn)多個(gè)功能

public class LambdaDemo04 {

    /**
     * 通過flag判斷是通過顏色過濾
     * flag=true 顏色過濾
     * flag=false 重量過濾
     *
     * @param appleList
     * @return
     */
    public static List<Apple> filterAppleColorAndWeigth(List<Apple> appleList,String color,int weight,boolean flag) {
        List<Apple> resultList = new ArrayList<>();
        for (Apple apple : appleList) {
            if ((flag && apple.getColor().equals(color)) || (!flag && apple.getWeight().equals(weight))) {
                resultList.add(apple);
            }
        }
        return resultList;
    }


    public static void main(String[] args) {
        // 1痪伦、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));
        // 2侄榴、過濾紅色蘋果
        List<Apple> resultList1 = filterAppleColorAndWeigth(apples,"紅色",200,true);
        System.out.println("==============紅色==================");
        resultList1.forEach(System.out::println);
        // 3雹锣、過濾綠色蘋果
        List<Apple> resultList2 = filterAppleColorAndWeigth(apples,"綠色",200,false);
        System.out.println("==============綠色==================");
        resultList2.forEach(System.out::println);

    }
}

上面的代碼,看起來確實(shí)挺優(yōu)化的癞蚕,可以一個(gè)方法解決兩個(gè)問題蕊爵,但是這閱讀性太差了,而且不方便維護(hù)涣达。

  • true / false 是什么意思呢在辆?
  • 此外如果要解決更多變化和需求,比如大小度苔,形狀匆篓,場地,又該怎么辦呢寇窑?估計(jì)會(huì)有很多的filterxxxxx方法吧鸦概!

第三次優(yōu)化:行為參數(shù)化

通過前面已經(jīng)看到,你需要一種比添加很多參數(shù)更好的方法來應(yīng)對(duì)變化的需求甩骏。讓你把代碼往更高層次進(jìn)行重構(gòu)和封裝怎么買做呢窗市?。如下

  • 方法的標(biāo)準(zhǔn)建模
image-20211021210249021.png
image-20211021210340955.png

什么是標(biāo)準(zhǔn)建模呢饮笛?

就是用面向?qū)ο蟮姆绞剑航涌诨刹臁6x一個(gè)接口來對(duì)選擇進(jìn)行標(biāo)準(zhǔn)建模如下:

定義接口:

public interface ApplePredicate {
    boolean test(Apple apple);
}

采用多實(shí)現(xiàn)的方式,代表不同的選擇標(biāo)準(zhǔn)如下:

顏色實(shí)現(xiàn):

public class ApplePredicateColor implements ApplePredicate {
    public boolean test(Apple apple) {
        return apple.getColor().equals("紅色");
    }
}

重量實(shí)現(xiàn):

public class ApplePredicateWeigth implements ApplePredicate {
    public boolean test(Apple apple) {
        return apple.getWeight() > 200;
    }
}

測(cè)試

public class LambdaDemo01 {

    // 入?yún)榻涌陬愋停篈ppPredicate福青,方便向下兼容
    public static List<Apple> filterAppleColorAndWeigth(List<Apple> appleList,AppPredicate predicate) {
        List<Apple> resultList = new ArrayList<>();
        for (Apple apple : appleList) {
            if (predicate.test(apple)) {
                resultList.add(apple);
            }
        }
        return resultList;
    }



    public static void main(String[] args) {
        // 1摄狱、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));
        apples.add(new Apple(6, "紅色", 210));
        // 2、過濾紅色蘋果
        List<Apple> resultList1 = filterAppleColorAndWeigth(apples,new AppPredicateColor());
        System.out.println("==============紅色==================");
        resultList1.forEach(System.out::println);
        // 3无午、重量200g的蘋果
        List<Apple> resultList2 = filterAppleColorAndWeigth(apples,new AppPredicateWeight());
        System.out.println("==============重量200g的蘋果==================");
        resultList2.forEach(System.out::println);
        // 3媒役、重量200g的蘋果 并且是紅色的
        List<Apple> resultList3= filterAppleColorAndWeigth(apples,new AppPredicateWeightColor());
        System.out.println("==============重量200g的蘋果 并且是紅色的==================");
        resultList3.forEach(System.out::println);

    }
}

通上面的方式,我把相同邏輯業(yè)務(wù)用接口進(jìn)行定義方法宪迟,然后各種子類去去實(shí)現(xiàn)酣衷,在調(diào)用的過程中去選擇和匹配對(duì)應(yīng)的算法。稱之為:==“策略者模式”==

策略者模式其實(shí)就是:它讓你定義一族算法次泽,把它們封裝起來(稱之為:策略)穿仪,然后在運(yùn)行時(shí)選擇一個(gè)算法,在這里意荤。算法族就是:ApplePredicate牡借,這里的ApplePredicateWeigth、ApplePredicateColor就是它的不同策略袭异。

通過上面,其實(shí)我們已經(jīng)做了意見很酷的事情炬藤,我們只需要傳遞接口的引用對(duì)象御铃,就可以達(dá)到不同的過濾效果碴里,達(dá)到了設(shè)計(jì)模式的要求,對(duì)內(nèi)修改關(guān)閉上真,對(duì)外修改擴(kuò)展咬腋。換句話說:filterXXXX方法的行為被參數(shù)化了。也就是行為參數(shù)化的過程睡互。

小結(jié)

以后在開發(fā)中根竿,如果調(diào)用任何一個(gè)方法,如果這個(gè)方法中有傳遞了接口或者抽象類作為參數(shù)就珠,說明你這個(gè)方法肯定的有一部分邏輯肯定要延遲的外部來執(zhí)行寇壳。我們把這種行為成為:行為參數(shù)化。

策略模式缺陷

目前妻怎,當(dāng)要把新的行為傳遞給filterxxx方法的時(shí)候壳炎,你不得不申明好幾個(gè)或者若干個(gè)ApplePredicate的實(shí)現(xiàn)類,這真的很啰嗦和很費(fèi)時(shí)間逼侦。怎么拯救它呢匿辩?

答案就是:Java的匿名內(nèi)部類。匿名內(nèi)部類可以讓你==同時(shí)申明和實(shí)例化一個(gè)類(接口榛丢,抽象類)==铲球。它可以改善上面的代碼。讓它變得更加的簡潔晰赞。但是我們通過下面的學(xué)習(xí)稼病,匿名內(nèi)部類確實(shí)可以簡化,但是也不完全令人滿意宾肺,因?yàn)橛懈玫姆绞骄褪莏dk1.8引入的Lamdba表達(dá)式溯饵。

匿名內(nèi)部類

第四次優(yōu)化:匿名內(nèi)部類

匿名內(nèi)部類:可以使你的代碼更加簡潔,你可以在定義一個(gè)類(接口锨用,抽象類)的同時(shí)對(duì)其進(jìn)行實(shí)例化丰刊。它與局部類很相似,不同的是它沒有類名增拥,如果某個(gè)局部類你只需要用一次啄巧,那么你就可以使用匿名內(nèi)部類

換句話說:匿名內(nèi)部類是一種允許你==隨建隨用==創(chuàng)建對(duì)象和覆蓋行為方法的一種機(jī)制。


public class ApplePredicateTest {

    /**
     * 行為參數(shù)化
     * @param appleList
     * @param predicate 接口
     * @return
     */
    public static List<Apple> filterApple(List<Apple> appleList, ApplePredicate predicate){
        List<Apple> resultList = new ArrayList<>();
        for (Apple apple : appleList) {
            // 調(diào)用ApplePredicate子類的具體行為
            if (predicate.test(apple)) {
                resultList.add(apple);
            }
        }
        return resultList;
    }

    public static void main(String[] args) {
        // 1掌栅、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));
        // 2秩仆、使用匿名內(nèi)部類過濾紅色蘋果
        List<Apple> resultList1 = filterApple(apples, new ApplePredicate() {
            // 具體內(nèi)部類行為動(dòng)作
            @Override
            public boolean test(Apple apple) {
                return apple.getColor().equals("紅色");
            }
        });
        System.out.println("==============紅色==================");
        resultList1.forEach(System.out::println);

        // 3、使用匿名內(nèi)部類過濾總量超過200g
        List<Apple> resultList2 = filterApple(apples, new ApplePredicate() {
            // 具體內(nèi)部類行為動(dòng)作
            @Override
            public boolean test(Apple apple) {
                return apple.getWeight() > 200;
            }
        });
        System.out.println("==============重量大于200g==================");
        resultList2.forEach(System.out::println);
    }

}

是不是體現(xiàn)出了他的:隨建隨用的效果呢猾封?太棒了澄耍。

經(jīng)典的匿名內(nèi)部類謎題

public class Anonymous {

   public final int value = 4;
   public void doIt(){
       int value = 6;
       Runnable runnable = new Runnable() {
           public final int value = 5;
           @Override
           public void run() {
               int value = 10;
               System.out.println(this.value);
           }
       };

       runnable.run();
   }

    public static void main(String[] args) {
        Anonymous anonymous = new Anonymous();
        anonymous.doIt();
    }
}

答案是:5

通過Debug可以看出來,當(dāng)前this對(duì)象指的是當(dāng)前內(nèi)部類對(duì)象中的value值,如果把this給去了齐莲,那就是當(dāng)前方法里面的值痢站。

image-20220104220057259.png

匿名內(nèi)部類的理解

  • 使用匿名內(nèi)部類:起到保護(hù)和安全的作用。
  • 匿名內(nèi)部類:是一種允許你==隨建隨用==創(chuàng)建對(duì)象和覆蓋行為方法的一種機(jī)制选酗≌竽眩可以解決在開發(fā)中需求不停變化的問題。
  • 我舉個(gè)例子:在開發(fā)中如果客戶提供不同的需求芒填,傳統(tǒng)的方式是通過接口擴(kuò)展子類進(jìn)行實(shí)現(xiàn)呜叫,但是需求變化如果太多,我們就定義很多的實(shí)現(xiàn)類殿衰,這樣給后續(xù)的維護(hù)和擴(kuò)展都提供了不便朱庆,如果業(yè)務(wù)組合的需求過多,子類也就越多播玖,就越來越不靈活椎工。我們可以利用匿名內(nèi)部類的的隨建隨用的機(jī)制很好的解決子類過多和需求變化過多的情況,廣泛應(yīng)用在比如:jdbctempalte的增刪改查中蜀踏,GUI维蒙,Swing事件行為中,以及stream流中比如:filter,map,sorted方法中果覆,以及底層源碼都可以看到匿名內(nèi)部類的身影颅痊。
  • 其實(shí)也它就是在定義一個(gè)類(接口,抽象類)的同時(shí)對(duì)其進(jìn)行實(shí)例化局待。實(shí)例化的每一次都會(huì)在當(dāng)前類下生成一個(gè)==當(dāng)前類$count的類==斑响,這個(gè)類也就就是匿名類的具體類的實(shí)現(xiàn),可以在target目錄下可以看到钳榨。如果實(shí)例化多次匿名類舰罚,count就會(huì)進(jìn)行累加。

什么時(shí)候用匿名內(nèi)部類還是用實(shí)現(xiàn)類呢

  • 使用匿名內(nèi)部類:需求不明確薛耻,可以考慮定義接口营罢,不管了直接讓調(diào)用過程中去確定即可或者只有一種情況
  • 如果明確,建議一個(gè)接口饼齿,具體實(shí)現(xiàn)類饲漾,比如:支付:IPayService的 微信WexinPlayService AlipayService

問題

  • 但是匿名內(nèi)部類還是不夠好,第一它往往很笨重缕溉,因?yàn)樗加煤芏嗫臻g考传。
  • 怎么拯救呢?Lambda表達(dá)式

我們可以通過Java8里面提供的Lambda表達(dá)式進(jìn)行優(yōu)化和處理如下:

public class ApplePredicateTest {
    public static List<Apple> filterApple(List<Apple> appleList, ApplePredicate predicate){
        List<Apple> resultList = new ArrayList<>();
        for (Apple apple : appleList) {
            if (predicate.test(apple)) {
                resultList.add(apple);
            }
        }
        return resultList;
    }

    public static void main(String[] args) {
        // 1证鸥、蘋果庫存
        List<Apple> apples = new ArrayList<>();
        apples.add(new Apple(1, "紅色", 200));
        apples.add(new Apple(2, "綠色", 100));
        apples.add(new Apple(3, "紅色", 134));
        apples.add(new Apple(4, "淺紅色", 400));
        apples.add(new Apple(5, "淺綠色", 220));
        // 2僚楞、Lambda表達(dá)式過濾紅色蘋果
        List<Apple> resultList1 = filterApple(apples, apple->apple.getColor().equals("紅色"));
        System.out.println("==============紅色==================");
        resultList1.forEach(System.out::println);

        // 3勤晚、Lambda表達(dá)式過濾總量超過200g
        List<Apple> resultList2 = filterApple(apples, apple->  apple.getWeight() > 200);
        System.out.println("==============重量大于200g==================");
        resultList2.forEach(System.out::println);
    }

}

我們不得不承認(rèn)看上去比之前干凈多了,也很好看镜硕,因?yàn)榭雌饋砀駟栴}陳述本身运翼,也解決了我們啰嗦的問題。

多線程中的匿名內(nèi)部類處理方式

package java.lang;

/**
 * The <code>Runnable</code> interface should be implemented by any
 * class whose instances are intended to be executed by a thread. The
 * class must define a method of no arguments called <code>run</code>.
 * <p>
 * This interface is designed to provide a common protocol for objects that
 * wish to execute code while they are active. For example,
 * <code>Runnable</code> is implemented by class <code>Thread</code>.
 * Being active simply means that a thread has been started and has not
 * yet been stopped.
 * <p>
 * In addition, <code>Runnable</code> provides the means for a class to be
 * active while not subclassing <code>Thread</code>. A class that implements
 * <code>Runnable</code> can run without subclassing <code>Thread</code>
 * by instantiating a <code>Thread</code> instance and passing itself in
 * as the target.  In most cases, the <code>Runnable</code> interface should
 * be used if you are only planning to override the <code>run()</code>
 * method and no other <code>Thread</code> methods.
 * This is important because classes should not be subclassed
 * unless the programmer intends on modifying or enhancing the fundamental
 * behavior of the class.
 *
 * @author  Arthur van Hoff
 * @see     java.lang.Thread
 * @see     java.util.concurrent.Callable
 * @since   JDK1.0
 */
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

public class ApplePredicateTest03 {

    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            System.out.println("Hello Thread");
        });

        thread.start();
    }

}

總結(jié)

  • 行為參數(shù)化兴枯,就是一個(gè)方法接受多個(gè)不同行為的作為參數(shù),并在內(nèi)部使用它們矩欠。完成不能行為的能力财剖。
  • 行為參數(shù)化可以讓代碼更好地使用不斷變化的要求,減輕未來的工作量癌淮。
  • 傳遞代碼躺坟,就是講新行為作為參數(shù)傳遞給方法。但是在JDK8之前實(shí)現(xiàn)起來很啰嗦乳蓄,為接口申明許多只用一次的實(shí)現(xiàn)子類而造成啰嗦代碼咪橙。在JDK1.8之前可以使用匿名內(nèi)部類來減少。
  • JavaApi包含很多可以用不同行為進(jìn)行參數(shù)的方法虚倒,包括:排序美侦,多線程和GUI處理等。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末魂奥,一起剝皮案震驚了整個(gè)濱河市菠剩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耻煤,老刑警劉巖具壮,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異哈蝇,居然都是意外死亡棺妓,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門炮赦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怜跑,“玉大人,你說我怎么就攤上這事眼五∽彼遥” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵看幼,是天一觀的道長批旺。 經(jīng)常有香客問我,道長诵姜,這世上最難降的妖魔是什么汽煮? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上暇赤,老公的妹妹穿的比我還像新娘心例。我一直安慰自己,他們只是感情好鞋囊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布止后。 她就那樣靜靜地躺著,像睡著了一般溜腐。 火紅的嫁衣襯著肌膚如雪译株。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天挺益,我揣著相機(jī)與錄音歉糜,去河邊找鬼。 笑死望众,一個(gè)胖子當(dāng)著我的面吹牛匪补,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播烂翰,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼夯缺,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了刽酱?” 一聲冷哼從身側(cè)響起喳逛,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棵里,沒想到半個(gè)月后润文,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡殿怜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年典蝌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片头谜。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骏掀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柱告,到底是詐尸還是另有隱情截驮,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布际度,位于F島的核電站葵袭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏乖菱。R本人自食惡果不足惜坡锡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一蓬网、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鹉勒,春花似錦帆锋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绵疲,卻和暖如春哲鸳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盔憨。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留讯沈,地道東北人郁岩。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像缺狠,于是被迫代替她去往敵國和親问慎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容