<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    LetsCoding.cn

    天地之間有桿秤,拿秤砣砸老百姓。

    Java 8:Lambda表達式(一)

    Java 8中,最重要的一個改變使得代碼更快、更簡潔,并向FP(函數式編程)打開了方便之門。下面我們來看看,它是如何做到的。

    在上世紀九十年代,Java被設計成了OOP語言,在當時,OOP是軟件開發中的標桿。遠在OOP還沒有出現的時候,已經產生了FP語言,例如Lisp和Scheme,但是它們的益處,并沒有受到學術圈外的人重視。最近,FP的重要性被提升了,因為它非常適合并發編程和事件驅動編程。然而,這并不意味著OO不好,相反,好的策略應該是混用OOP和FP。就算你對并發編程不感興趣,這也很有道理。例如,如果編程語言有一個方便寫函數表達式的語法,集合類庫就能擁有強大的API。

    Java 8中最主要的增強,就是把FP的概念深度整合進OO。在本文中,我將會展示其基本語法以及,在不同的上下文中,如何使用它。關鍵點如下:

    • Lambda表達式,就是有參數的代碼塊。
    • 在任何時候,你想稍后執行一個代碼塊時,用Lambda表達式。
    • Lambda表達式可以被轉型成函數式接口。
    • Lambda表達式可以從封閉作用域有效訪問final的變量。
    • 方法和構造器的引用可在不調用它們的情況下引用它們。
    • 你現在可以把default和static方法的具體實現寫在接口中。
    • 你必須手動解決不同接口中任何的default方法沖突。
    • 為什么需要Lambda表達式?

      Lambda表達式是一個代碼塊,你可以繞過它,因此它能在稍后執行,僅一次或多次。在介紹語法(甚至是奇怪的名稱)之前,讓我們后退一步,看看一直以來,你在Java中,類似的代碼塊會在什么地方用到。

      當你想在一個獨立的線程中執行代碼時,你把代碼放到Runnable的run方法中,就像這樣:

      1. class Worker implements Runnable {
      2.      public void run() {
      3.          for (int i = 0; i < 1000; i++)
      4.              doWork();
      5.      }
      6.      // …
      7. }

      然后,當你想執行這段代碼時,你創建一個Worker實例,把它提交給線程池,或者簡單的開始一個新線程:

      1. Worker w = new Worker();
      2. new Thread(w).start();

      這里的關鍵點在于,run方法中包含你想在獨立線程中執行的代碼。

      想想用自定義的Comparator排序。如果你想以長度,而不以默認的字典順序對字符串排序,你可以傳遞一個Comparator對象給sort方法:

      1. class LengthComparator implements Comparator< String > {
      2.      public int compare(String first, String second) {
      3.          return Integer.compare(first.length(), second.length());
      4.      }
      5. }
      6.    
      7. Arrays.sort(strings, new LengthComparator());

      sort方法會持續調用compare方法,重排亂序的元素,直到數組排序完畢。你給sort方法傳遞一個比較元素的代碼片段,這段代碼被整合進其余的、你也許不想重新去實現的排序邏輯。注意:如果 x等于y,Integer.compare(x, y)返回0;x < y,返回負數;x > y,返回正數。這個static方法在Java 7中被加入。你千萬不能計算x - y來比較它們的大小,那樣符號相反的大操作數會導致計算溢出的。

      作為另外一個延后執行的例子,考慮一個按鈕回調。你新建一個繼承Listener接口的類,把回調動作放進其中,創建它的一個實例,最后把實例注冊到按鈕。這種場景司空見慣,以至于很多程序員都使用“匿名類的匿名實例”語法:

      1. button.setOnAction(new EventHandler< ActionEvent >() {
      2.     public void handle(ActionEvent event) {
      3.         System.out.println("Thanks for clicking!");
      4.     }
      5. });

      重要的是handle方法中的代碼,任何時候按鈕被點擊,它就會被執行。

      因為Java 8把JavaFX作為Swing GUI工具包的繼任者,我在例子里是使用JavaFX。這些細節并不重要,因為在所有的UI工具包中,不管是Swing,JavaFX,還是Android,都是你給按鈕一些代碼,在按鈕被點擊的時候執行。

      在上面的三個例子中,你看到了相同的方式。代碼塊被傳遞給某人:線程池,sort方法或按鈕,它將在稍后被調用。

      到現在為止,在Java中傳遞代碼塊并不簡單。你不能只是傳遞代碼塊,Java是一個OOP語言,因此你必須先創建一個屬于某個類的實例,而這個類擁有我們需要傳遞的代碼塊。

      在其他語言中,是可能直接使用代碼塊的。在很長一段時間里,Java的設計者們反對增加這個特性,畢竟,Java的偉大力量在于簡單性和一致性。如果一個語言,包含所有的能夠產生少量更緊湊代碼的特性,它就會變成不可維護的一團糟。經管如此,在其他語言中,它們并不僅僅是可以更簡單的啟動一個線程,或者注冊一個按鈕點擊的處理程序;它們中的大量API都更加簡單,更加一致,更加強大。在Java里,人們本應該能夠寫出類似的API,它們使用繼承特定函數的類的實例,但是,這樣的API,讓人用起來并不愉快。

      一段時間以來,問題變成,并不是要不要在Java中添加FP,而是怎么去添加。在符合Java的設計出來之前,設計者們花了幾年的時間來做試驗。在本文下一部分,你將會看到,你是如何在Java 8中使用代碼塊的。

      Lambda表達式的語法

      再想想上面排序的例子。我們傳遞比較字符串長度的代碼。我們計算:

      1. Integer.compare(first.length(), second.length())

      fisrt和second是什么?它們都是字符串!Java是強類型語言,我們也必須指明這一點:

      1. (String first, String second) -> Integer.compare(first.length(), second.length())

      你看到了你的第一個Lambda表達式。它只是簡單的代碼塊和必須傳給它的變量說明。

      它的名稱Lambda是怎么來的呢?很多年前,還在計算機出現之前,邏輯學家Alonzo Church想要形式化數學函數,讓它具有更有效的可計算性。(奇怪的事,人們知道有些函數的存在,卻沒有人知道怎么計算它們的值。)他用希臘字母lambda(λ)來表示函數參數。如果他懂得Jav API,他可能會這樣寫:

      1. λfirst.λsecond.Integer.compare(first.length(), second.length())

      那為什么是字母λ呢?是Church用完了其他所有的字母了嗎?實際上,偉大的《數學原理》使用ˆ來表示自由變量,它激發了Church用一個大寫的lambda(λ)表示參數的靈感。但是最終,他還是使用了小寫版本。自此以后,一個擁有參數的表達式就被稱為了“Lambda表達式”。

      本文譯自:Lambda Expressions in Java 8

    原創文章,轉載請注明: 轉載自LetsCoding.cn
    本文鏈接地址: Java 8:Lambda表達式(一)

    posted on 2014-05-11 12:06 Rolandz 閱讀(1677) 評論(1)  編輯  收藏 所屬分類: 編程實踐

    評論

    # re: Java 8:Lambda表達式(一) 2014-06-01 19:13 手賺網-手機賺錢軟件排行,手機賺錢平臺,網絡賺錢http://www.szapk.cn

    手賺網-手機賺錢軟件排行,手機賺錢平臺,網絡賺錢http://www.szapk.cn!!  回復  更多評論   

    導航

    統計

    留言簿(1)

    隨筆分類(12)

    隨筆檔案(19)

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲另类激情综合偷自拍| 亚洲视频一区二区| 久久久亚洲欧洲日产国码aⅴ| 四虎影视永久在线精品免费| 日本一区免费电影| 国产区图片区小说区亚洲区| 免费久久精品国产片香蕉| 国产成人亚洲毛片| 亚洲男女内射在线播放| 岛国精品一区免费视频在线观看| 久久综合亚洲色HEZYO国产| 最近免费字幕中文大全| 亚洲av无码专区国产乱码在线观看 | 国产日韩AV免费无码一区二区| 亚洲午夜av影院| 中文字幕乱码免费看电影| 97久久精品亚洲中文字幕无码| 亚欧免费视频一区二区三区| 亚洲a级成人片在线观看| 在线成人a毛片免费播放| 男人j进女人p免费视频| 国产AV无码专区亚洲A∨毛片| 欧洲人成在线免费| 亚洲AV色吊丝无码| www国产亚洲精品久久久| 中国好声音第二季免费播放| 91亚洲国产在人线播放午夜| 24小时免费直播在线观看| 欧洲乱码伦视频免费国产| 亚洲无线码一区二区三区| 亚洲一区免费在线观看| 亚洲乱亚洲乱妇24p| 久久久久国产亚洲AV麻豆 | 一个人看的免费观看日本视频www| 精品亚洲一区二区| 啦啦啦高清视频在线观看免费 | 久久精品免费电影| 亚洲精品GV天堂无码男同| 久久精品国产亚洲7777| av免费不卡国产观看| 成年网站免费入口在线观看|