Java 8 實(shí)戰(zhàn)學(xué)習(xí)「行為參數(shù)化」

Java 8 實(shí)戰(zhàn)學(xué)習(xí)

java 8 已經(jīng)出來(lái)和長(zhǎng)時(shí)間了发笔,作為一個(gè) AndroidDevepler 來(lái)說的現(xiàn)在還沒有機(jī)會(huì)在 studio 直接使用 java8 的新特性漂彤,但是谷歌官方宣布 AndroidStudio 2.4 以后就可以支持 java8 的一些新特性輕重就包括 lambda 毛萌,關(guān)于 java8 網(wǎng)上有很多教程历恐,但是「書中得來(lái)終覺淺买置,覺知此時(shí)要躬行」瓶蚂,所以我決定把 《 Java8 實(shí)戰(zhàn) 》親自閱讀實(shí)踐一下。

行為參數(shù)化

書中通過 普通實(shí)現(xiàn) -> 抽取行為參數(shù) -> 匿名內(nèi)部類實(shí)現(xiàn)這個(gè)具體行為 -> 引入 lambda 表達(dá)式讓代碼更簡(jiǎn)潔 夏跷。 來(lái)幫助我們理解 lambda 的由來(lái)哼转。


普通實(shí)現(xiàn)

書中列舉了根據(jù)不同條件篩選蘋果的例子:起初我們?nèi)绻枰Y選蘋果的顏色我們會(huì)這么寫:

    public static List<Apple> filterGreenApples(List<Apple> inventory) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
           if ("green".equals(apple.getColor())){
                result.add(apple);
            }
        } return result;
    }

如果我們需要篩選蘋果的重量我們需要這么寫:

   public static List<Apple> filterWeightApples(List<Apple> inventory) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
           if (apple.getWeight() > 10){
                result.add(apple);
            }
        } return result;
    }

這樣看起來(lái)代碼就很冗余,必定不同連個(gè)代碼不同之處就是 『篩選的行為的條件』 不同槽华,按照面向?qū)ο蟮乃枷耄骸敢粋€(gè)良好的原則是在編寫類似的代碼之后壹蔓,嘗試將其抽象化」。


篩選條件抽取為接口

所以我們將篩選條件抽取為一個(gè)參數(shù)猫态,該參數(shù)由一個(gè)抽象的接口承擔(dān):

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

該接口的 test 方法即為蘋果篩選的條件佣蓉,具體篩選的邏輯由這個(gè)接口的實(shí)現(xiàn)來(lái)決定。是不是覺得很熟悉亲雪,我們最常用的 onClick 事件勇凭,就是這樣的一個(gè)接口。這樣以后我們的 filterApples的方法就可以修改為下面的實(shí)現(xiàn):

  public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (p.test(apple)) { // 謂詞對(duì)象p封裝了,測(cè)試蘋果的條件
                result.add(apple);
            }
        } return result;

    }

我們下面在使用的 filterApples 的時(shí)候就只需關(guān)注 ApplePredicate 的實(shí)現(xiàn)就好了义辕。表面上看我們?cè)诘墓ぷ魇?ApplePredicate 的實(shí)現(xiàn)虾标,其實(shí)我們?cè)诔橄?filterApples 的時(shí)候就做到了:

filterApples 方法的行為取決于你通過 ApplePredicate 對(duì)象傳遞的代碼。換句話說灌砖,你把 filterApples 方法的行為參數(shù)化了璧函!

原翻譯中 filterApples 方法的行為參數(shù)化,我感覺翻譯為 filterApples 的「篩選行為」參數(shù)話了比較好基显。


通過匿名內(nèi)部類來(lái)減少不必要的接口實(shí)現(xiàn)類

但是這樣雖然我們完成了篩選條件的參數(shù)化蘸吓,但是問題是這樣每次我們都要實(shí)現(xiàn)這樣的一個(gè) ApplePredicate 具體實(shí)現(xiàn)類,在 lambda 出現(xiàn)之前我們是使用匿名內(nèi)部類來(lái)解決的续镇。

    List<Apple> redApples = filterApples(inventory, new ApplePredicate() {
        public boolean test(Apple apple) {
            return "red".equals(apple.getColor());
        }
    });

那么這樣的還是不太令人滿意美澳,因?yàn)槲覀冎?ApplePredicate 是 filterApples 的第二個(gè)參數(shù)(可推敲),真正需要我們決定的實(shí)現(xiàn)條件是 "red".equals(apple.getColor() ,如果我們能直接傳遞這句話制跟,來(lái)替代這些大括號(hào)就好了舅桩。用原書的話說就是:

即使匿名類處理在某種程度上改 善了為一個(gè)接口聲明好幾個(gè)實(shí)體類的 啰 嗦問題,但它仍不能令人滿意雨膨。在只需要傳遞一段簡(jiǎn)單的 代碼時(shí)(例如表示選擇標(biāo)準(zhǔn)的boolean表達(dá)式)擂涛,你還是要?jiǎng)?chuàng)建一個(gè)對(duì)象,明確地實(shí)現(xiàn)一個(gè)方法 來(lái)定義一個(gè)新的行為(例如Predicate中的test方法或是EventHandler中的handler方法)聊记。

如果我們使用 lambda 表達(dá)式來(lái)實(shí)現(xiàn)上邊的邏輯撒妈,看上去將會(huì)很清爽:

List<Apple> filterApple = filterApple(apples, (Apple apple) -> "red".equals(apple.getColor()));

函數(shù)接口的概念

書中第二章并沒有具體展開說明 lambda 表達(dá)式的使用,而是引入了 「行為參數(shù)化」 這個(gè)概念排监。 這個(gè)概念作為一個(gè) AndroidDeveloper 我們幾乎每天都在使用狰右。 比如: 網(wǎng)絡(luò)接口的回調(diào) CallBack 接口, 比如 setOnClickListener 中要傳遞的 View.OnClickListener 的接口舆床。此類接口在java用有一個(gè)專有的名詞就做函數(shù)接口:

Single Abstract Method interfaces 當(dāng)然首先是一個(gè)接口棋蚌,然后就是在這個(gè)接口里面只能有一個(gè)抽象方法

java 8 之前已經(jīng)有的函數(shù)接口

java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener

java8 新定義的函數(shù)式接口: java.util.function 中定義了幾組類型的函數(shù)式接口以及針對(duì)基本數(shù)據(jù)類型的子接口:

Predicate -- 傳入一個(gè)參數(shù),返回一個(gè)bool結(jié)果挨队, 方法為boolean test(T t)

Consumer -- 傳入一個(gè)參數(shù)谷暮,無(wú)返回值,純消費(fèi)盛垦。 方法為void accept(T t) 如:List.forEach(Consumer c) 方法

Function -- 傳入一個(gè)參數(shù)湿弦,返回一個(gè)結(jié)果,方法為R apply(T t)

Supplier -- 無(wú)參數(shù)傳入腾夯,返回一個(gè)結(jié)果颊埃,方法為T get()

UnaryOperator -- 一元操作符, 繼承Function,傳入?yún)?shù)的類型和返回類型相同蝶俱。

BinaryOperator -- 二元操作符竟秫, 傳入的兩個(gè)參數(shù)的類型和返回類型相同, 繼承BiFunction

這一章我們主要了解了什么是函數(shù)式接口并引入了 lambda 可以解決函數(shù)式接口以及匿名內(nèi)部類實(shí)現(xiàn)的啰嗦跷乐,在下一偏我們將學(xué)習(xí) lambda 可以解決哪些,以及如何解決這個(gè)啰嗦的問題趾浅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末愕提,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子皿哨,更是在濱河造成了極大的恐慌浅侨,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件证膨,死亡現(xiàn)場(chǎng)離奇詭異如输,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門不见,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)澳化,“玉大人,你說我怎么就攤上這事稳吮《泄龋” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵灶似,是天一觀的道長(zhǎng)列林。 經(jīng)常有香客問我,道長(zhǎng)酪惭,這世上最難降的妖魔是什么希痴? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮春感,結(jié)果婚禮上砌创,老公的妹妹穿的比我還像新娘。我一直安慰自己甥厦,他們只是感情好纺铭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著刀疙,像睡著了一般舶赔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谦秧,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天竟纳,我揣著相機(jī)與錄音,去河邊找鬼疚鲤。 笑死锥累,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的集歇。 我是一名探鬼主播桶略,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼诲宇!你這毒婦竟也來(lái)了际歼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤姑蓝,失蹤者是張志新(化名)和其女友劉穎鹅心,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纺荧,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旭愧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年颅筋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片输枯。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡议泵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出用押,到底是詐尸還是另有隱情肢簿,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布蜻拨,位于F島的核電站池充,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏缎讼。R本人自食惡果不足惜收夸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望血崭。 院中可真熱鬧卧惜,春花似錦、人聲如沸夹纫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舰讹。三九已至茅姜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間月匣,已是汗流浹背钻洒。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锄开,地道東北人素标。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像萍悴,于是被迫代替她去往敵國(guó)和親头遭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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