學習札記-Java8系列-2-Lambda表達式-敲開函數(shù)式編程的大門

學習札記-Java8系列-2-Lambda表達式-敲開函數(shù)式編程的大門

面向?qū)ο蟮氖`

在正式講Lambda表達式和函數(shù)式編程之前我們先完成一個需求分析一下我們之前面向?qū)ο缶幊痰牟蛔悖?/p>

需求:啟動一個線程并輸出一句話

    @Test
    public void testTradition() throws Exception {
        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println("使用傳統(tǒng)方式開啟線程");
            }
        }).start();
    }

本著“萬物皆對象”的思想,創(chuàng)建一個Runnable接口的匿名內(nèi)部類對象(線程對象)來指定任務內(nèi)容肤寝,再啟動該線程始衅。這種做法是Ok的,但是……

我們真的想創(chuàng)建一個匿名內(nèi)部類對象嗎?

不兔辅。我們只是為了做這件事情而不得不創(chuàng)建一個對象数初。

我們真正希望做的事情是:將 run方法方法體內(nèi)的代碼傳遞給Thread類鹤啡。

傳遞并執(zhí)行這一段代碼肌稻,才是我們真正的目的清蚀。

而創(chuàng)建對象只是受限于面向?qū)ο笳Z法而不得不采取的一種手段方式。

那爹谭,有沒有更加簡單的辦法枷邪?

如果我們將關注點從“怎么做”回歸到“做什么”的本質(zhì)上,就會發(fā)現(xiàn)只要能夠更好地達到目的诺凡,過程與形式其實并不重要东揣。

函數(shù)式編程的解放

函數(shù)式編程思想讓我們更加關注我們的目標也就是:“做什么”

@Test

public void testLambda() throws Exception {

    new Thread(()->System.out.println("使用Lambda方式開啟線程")).start();;

}

這段代碼和剛才的執(zhí)行效果是完全一樣的。

從代碼的語義中可以看出:我們啟動了一個線程腹泌,而線程任務的內(nèi)容以一種更加簡潔的形式被指定救斑。

瞬間感覺得到了解放!不再有“不得不創(chuàng)建 Runnable接口對象”的束縛真屯,不再有“覆蓋重寫抽象方法”的負擔,就是這么簡單穷娱!

總結(jié):

Java語言一大特點與優(yōu)勢就是面向?qū)ο蟀竽瑁请S著技術的發(fā)展,我們會發(fā)現(xiàn)面向?qū)ο笏枷朐谀承﹫鼍跋虏⒎鞘亲顑?yōu)的思想泵额。能夠簡單快速滿足需求配深、達到目標效果的思想有時候可能更加適合。這種思想就是函數(shù)式編程思想嫁盲!Java8中的Lambda表達式就可以讓我們把這種思想發(fā)揮的淋漓盡致篓叶!

感覺不過癮烈掠?那我們再來幾個案例對比下!

感受函數(shù)式編程的魅力-應對不斷變化的需求

需求:

根據(jù)用戶提出的不同條件篩選出滿足相應條件的商品缸托,比如:

篩選出所有名稱包含手機的商品

篩選出所有價格大于1000的商品

準備工作

方式一:傳統(tǒng)做法

@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Product {
private Long id; //商品編號
private String name; //商品名稱
private Double price;; //商品價格
}

//需求:篩選出所有名稱包含手機的商品

//需求:篩選出所有價格大于1000的商品

public class MagicLambda {
    private List<Product> products = new ArrayList<>();

    @Before
    public void init(){
      products.add(new Product(1L,"蘋果手機",8888.88));
      products.add(new Product(2L,"華為手機",6666.66));
      products.add(new Product(3L,"聯(lián)想筆記本",7777.77));
      products.add(new Product(4L,"機械鍵盤",999.99));
      products.add(new Product(5L,"雷蛇鼠標",222.22));
}

}

我們先使用傳統(tǒng)Java編程完成以下幾個需求,代碼如下:

 //需求:篩選出所有名稱包含手機的商品
public List<Product> filterProductByName(List<Product> products){
    List<Product> list = new ArrayList<>();
    for (Product product : products) {
        if (product.getName().contains("手機")) {
            list.add(product);
        }
    }
    return list;
}
//需求:篩選出所有價格大于1000的商品
public List<Product> filterProductByPrice(List<Product> products){
    List<Product> list = new ArrayList<>();
    for (Product product : products) {
        if (product.getPrice() > 1000) {
            list.add(product);
        }
    }
    return list;
}
@Test
public void test1() throws Exception {
    //List<Product> list = filterProductByName(products);
    List<Product> list = filterProductByPrice(products);
    for (Product product : list) {
        System.out.println(product);
    }
}    

完成需求后我們發(fā)現(xiàn)了問題左敌,針對不同的需求我們要寫不同的方法實現(xiàn),而每一個不同的實現(xiàn)我們需要編寫不同的方法俐镐,這里是不是可以使用策略設計模式優(yōu)化一下矫限?

完成需求后我們發(fā)現(xiàn)了問題,針對不同的需求我們要寫不同的方法實現(xiàn)佩抹,而每一個不同的實現(xiàn)我們需要編寫不同的方法叼风,這里是不是可以使用策略設計模式優(yōu)化一下?

方式二:使用策略設計模式優(yōu)化

編寫策略接口

public interface MyPredicate<T> {
    boolean test(T t);
}

編寫策略實現(xiàn)類

public class FilterProductByName implements MyPredicate<Product> {
    @Override
    public boolean test(Product t) {
        return t.getName().contains("手機");
    }
}
 
public class FilterProductByPrice implements MyPredicate<Product> {
    @Override
    public boolean test(Product t) {
        return t.getPrice() > 1000;
    }
}

修改方法實現(xiàn)

修改方法實現(xiàn)

public List<Product> filterProduct(List<Product> products,MyPredicate<Product> predicate){
    List<Product> list = new ArrayList<>();
    for (Product product : products) {
        if (predicate.test(product)) {
            list.add(product);
        }
    }
    return list;
}

@Test
public void test2() throws Exception {
    List<Product> list = filterProduct(products, new FilterProductByName());
    //List<Product> list = filterProduct(products, new FilterProductByPrice());
    for (Product product : list) {
        System.out.println(product);
    }
}

到這里我們又發(fā)現(xiàn)要針對不同的需求寫不同的策略類棍苹!很麻煩无宿!可不可以不寫?--使用匿名內(nèi)部類優(yōu)化枢里!

方式三:使用匿名內(nèi)部類優(yōu)化

@Test

public void test3() throws Exception {

    List<Product> list = filterProduct(products, new MyPredicate<Product>() {

        @Override

        public boolean test(Product t) {

            return t.getName().contains("手機");

        }

    });

    for (Product product : list) {

        System.out.println(product);

    }

}

到這里我們感覺還是很麻煩孽鸡!僅僅是想執(zhí)行一個比較判斷的條件表達式!卻要創(chuàng)建接口的匿名對象重寫抽象方法坡垫!很不爽梭灿,怎么辦?--使用Lambda表達式

方式四:使用Lambda表達式優(yōu)化

@Test

public void test4() throws Exception {

    filterProduct(products, (p) -> p.getPrice() > 1000).forEach(System.out::println);

}

到這里是不是已經(jīng)漸漸感受到了Lambda表達式的強大了冰悠?接下來更會讓你愛上她的堡妒!--使用Stream

(總結(jié)下:Lambda表達式可以理解為是一個匿名函數(shù),也就是一段可以傳遞的代碼(將代碼像數(shù)據(jù)一樣進行傳遞)溉卓∑こ伲可以寫出更簡潔、更靈活的代碼桑寨。作為一種更緊湊的代碼風格伏尼,使Java的語言表達能力得到了提升。)

方式五:使用Stream AP優(yōu)化

//獲取價格從高到低排行前三的商品信息

@Test

public void test5() throws Exception {

    //products.stream().filter(p -> p.getName().contains("蘋果")).forEach(System.out::println);

    //獲取價格從高到低排行前三的商品信息

    products.stream().sorted((x,y) -> y.getPrice().compareTo(x.getPrice())).limit(3).forEach(System.out::println);

}

到這里是不是已經(jīng)充分感受到了Java8函數(shù)式編程的強大和魅力了尉尾?那下一篇來我們就來揭下她神秘的面紗爆阶!

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沙咏,隨后出現(xiàn)的幾起案子辨图,更是在濱河造成了極大的恐慌,老刑警劉巖肢藐,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件故河,死亡現(xiàn)場離奇詭異,居然都是意外死亡吆豹,警方通過查閱死者的電腦和手機鱼的,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門理盆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人凑阶,你說我怎么就攤上這事猿规。” “怎么了晌砾?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵坎拐,是天一觀的道長。 經(jīng)常有香客問我养匈,道長哼勇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任呕乎,我火速辦了婚禮积担,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘猬仁。我一直安慰自己帝璧,他們只是感情好,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布湿刽。 她就那樣靜靜地躺著的烁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诈闺。 梳的紋絲不亂的頭發(fā)上渴庆,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音雅镊,去河邊找鬼襟雷。 笑死,一個胖子當著我的面吹牛仁烹,可吹牛的內(nèi)容都是我干的耸弄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼卓缰,長吁一口氣:“原來是場噩夢啊……” “哼计呈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起征唬,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤震叮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鳍鸵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡尉间,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年偿乖,在試婚紗的時候發(fā)現(xiàn)自己被綠了击罪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡贪薪,死狀恐怖媳禁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情画切,我是刑警寧澤竣稽,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站霍弹,受9級特大地震影響毫别,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜典格,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一岛宦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧耍缴,春花似錦砾肺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蚁趁,卻和暖如春裙盾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荣德。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工闷煤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涮瞻。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓鲤拿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親署咽。 傳聞我的和親對象是個殘疾皇子近顷,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

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