[Java8]使用JAVA8 Lambda Expressions 實現(xiàn) Monads(Functional Programming)

0x01 什么是Monads

簡單說,Monad就是一種設(shè)計模式甜无,表示將一個運算過程瓣铣,通過函數(shù)拆解成互相連接的多個步驟。你只要提供下一步運算所需的函數(shù)津辩,整個運算就會自動進行下去。
下面這兩篇文章通過圖解的方式講解了什么是Monads

0x02 為什么要使用Monads容劳?

一段不優(yōu)雅的例子

編程時檢查參數(shù)是否為null是最常見的功能喘沿。以下面的代碼為例子:

public static class Userdetails{
    public Address address;
    public Name name;
    
}

public static class Name{
    public String firstName;
    public String lastName;        
}

public static class Address{
    public String houseNumber;
    public Street street;
    public City city;
    
}

public static class Street{
    public String name;        
}

public static class City{
    public String name;        
}

現(xiàn)在我想獲得user.address.street.name,常見代碼如下:

 if(user == null )
    return null;
else if(user.address == null)
    return null;
else if(user.address.street == null)
    return null;
else
    return user.address.street.name;

這段檢測代碼淹沒了真正取值的代碼竭贩,閱讀性非常不優(yōu)雅

使用Monads來實現(xiàn)的例子

為了使用Lambda表達(dá)式蚜印,先定義一個函數(shù)接口: SingleArgExpression

package function;

/**
 * Created by haicheng.lhc on 13/04/2017.
 *
 * @author haicheng.lhc
 * @date 2017/04/13
 */
@FunctionalInterface
public interface SingleArgExpression<P, R> {

    public R function(P param);
}

然后創(chuàng)建一個類:Option

package function;

import java.lang.reflect.ParameterizedType;

/**
 * Created by haicheng.lhc on 13/04/2017.
 *
 * @author haicheng.lhc
 * @date 2017/04/13
 */
public class Option<T> {

    T value;

    public Option(T value) {
        this.value = value;
    }


    public <E> Option<E> flatMap(SingleArgExpression<T, Option<E>> mapper) {
        if (value == null) {
            return new Option<E>(null);
        }
        return mapper.function(value);

    }


    @Override
    public boolean equals(Object rhs) {
        if (rhs instanceof Option) {
            Option o = (Option) rhs;
            if (value == null) {
                return (o.value == null);
            } else {
                return value.equals(o.value);
            }
        } else {
            return false;
        }

    }

    @Override
    public int hashCode() {
        return value == null ? 0 : value.hashCode();
    }

    public T get() {
        System.out.println("hello");
        return value;
    }
}


接下來創(chuàng)建我們的測試類:OptionExample

package function;

/**
 * Created by haicheng.lhc on 13/04/2017.
 *
 * @author haicheng.lhc
 * @date 2017/04/13
 */
public class OptionExample {

    public static class Userdetails {

        public Option<Address> address = new Option<>(null);
        public Option<Name> name = new Option<>(null);

    }


    public static class Name {
        public Option<String> firstName = new Option<String>(null);
        public Option<String> lastName = new Option<String>(null);
    }


    public static class Address {
        public Option<String> houseNumber;
        public Option<Street> street;
        public Option<City> city;

    }


    public static class Street {
        public Option<String> name = new Option<>("alibaba");
    }


    public static class City {
        public Option<String> name;
    }

    public static void main(String[] args) {

        Option<Userdetails> userOpt = new Option<Userdetails>(new Userdetails());

        //And look how simple it is now
        String streetName = userOpt.flatMap(user -> user.address)
            .flatMap(address1 -> address1.street)
            .flatMap(street -> street.name)
            .get();
        System.out.println(streetName);

    }
}

可以看出,通過這個方法獲取user.address.street.name的時候留量,代碼是非常簡潔易懂的窄赋。

思路解析:
create a class Option that represents an optional value. And lets then have a map method that will run a lambda on its wrapped value and return another option. If the wrapped value is null, it will return an Option containing null without processing the lambda, thus avaoiding a null pointer exception

0x03 參考文章

https://www.javacodegeeks.com/2014/03/functional-programming-with-java-8-lambda-expressions-monads.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市楼熄,隨后出現(xiàn)的幾起案子忆绰,更是在濱河造成了極大的恐慌,老刑警劉巖可岂,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件错敢,死亡現(xiàn)場離奇詭異,居然都是意外死亡缕粹,警方通過查閱死者的電腦和手機稚茅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來平斩,“玉大人亚享,你說我怎么就攤上這事∷粒” “怎么了虹蒋?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長飒货。 經(jīng)常有香客問我,道長峭竣,這世上最難降的妖魔是什么塘辅? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮皆撩,結(jié)果婚禮上扣墩,老公的妹妹穿的比我還像新娘哲银。我一直安慰自己,他們只是感情好呻惕,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布荆责。 她就那樣靜靜地躺著,像睡著了一般亚脆。 火紅的嫁衣襯著肌膚如雪做院。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天濒持,我揣著相機與錄音键耕,去河邊找鬼。 笑死柑营,一個胖子當(dāng)著我的面吹牛屈雄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播官套,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼酒奶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奶赔?” 一聲冷哼從身側(cè)響起讥蟆,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纺阔,沒想到半個月后瘸彤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡笛钝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年质况,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玻靡。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡结榄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出囤捻,到底是詐尸還是另有隱情臼朗,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布蝎土,位于F島的核電站视哑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏誊涯。R本人自食惡果不足惜挡毅,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望暴构。 院中可真熱鬧跪呈,春花似錦段磨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至误阻,卻和暖如春债蜜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背堕绩。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工策幼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奴紧。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓特姐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親黍氮。 傳聞我的和親對象是個殘疾皇子唐含,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

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