LetsCoding.cn

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

          Java 8:Lambda表達式(一)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            在其他語言中,是可能直接使用代碼塊的。在很長一段時間里,Java的設計者們反對增加這個特性,畢竟,Java的偉大力量在于簡單性和一致性。如果一個語言,包含所有的能夠產生少量更緊湊代碼的特性,它就會變成不可維護的一團糟。經管如此,在其他語言中,它們并不僅僅是可以更簡單的啟動一個線程,或者注冊一個按鈕點擊的處理程序;它們中的大量API都更加簡單,更加一致,更加強大。在Java里,人們本應該能夠寫出類似的API,它們使用繼承特定函數(shù)的類的實例,但是,這樣的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是怎么來的呢?很多年前,還在計算機出現(xiàn)之前,邏輯學家Alonzo Church想要形式化數(shù)學函數(shù),讓它具有更有效的可計算性。(奇怪的事,人們知道有些函數(shù)的存在,卻沒有人知道怎么計算它們的值。)他用希臘字母lambda(λ)來表示函數(shù)參數(shù)。如果他懂得Jav API,他可能會這樣寫:

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

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

            本文譯自:Lambda Expressions in Java 8

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

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

          評論

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

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

          導航

          統(tǒng)計

          留言簿(1)

          隨筆分類(12)

          隨筆檔案(19)

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 汉寿县| 易门县| 紫阳县| 永安市| 榕江县| 同德县| 武平县| 江孜县| 宣化县| 临朐县| 桑日县| 阿城市| 金堂县| 石家庄市| 仪征市| 许昌市| 旺苍县| 梅州市| 民权县| 永修县| 鸡东县| 黄骅市| 汉沽区| 宁陕县| 保靖县| 黄浦区| 高淳县| 宝鸡市| 瑞安市| 阿瓦提县| 兴城市| 渭南市| 高淳县| 平南县| 屏边| 江源县| 黄梅县| 兴仁县| 景泰县| 新巴尔虎左旗| 吴忠市|