1. 程式人生 > >java1.8 lambda表示式 函數語言程式設計 閉包

java1.8 lambda表示式 函數語言程式設計 閉包

java1.8出來好久一直沒怎麼關注。這段時間公司的專案資料處理,需要頻繁操作集合,用for遍歷集合做計算,感覺很費勁,而且有大量重複程式碼。可讀性也不高。這時候想到java1.8新特性之一:函數語言程式設計

一、函式式介面 (functional interface)

@FunctionalInterface
interface DoSomeThing {
    int getAge(int a, int b);

    static void getName() {
        System.out.println("函式式介面的靜態方法");
    }

    default void getAge() {
        System.out.println("函式式介面的預設方法");
    }

}
@FunctionalInterface 可以不用加該註解,編譯的時候,對於只有一個抽象方法的介面,預設就是函式式介面。

如果一個方法接受一個函式式介面作為引數,那麼我們可以傳入以下型別作為引數:

  • 匿名內部類(Anonymous Inner Class)(Java的以前版本中經常使用的方式,在Java 8中不再被推薦
  • Lambda表示式
  • 方法或者構造器的引用(Method or Constructor Reference

二、閉包(closure)(回顧)

lambda表示式大量用到了閉包和函式回撥,java1.8之前不支援顯性閉包,要實現程式碼片段的傳遞,只能通過內部類的方式,模擬閉包。

閉包簡而言之就是 含有狀態的函式。

在java語言中,閉包的應用:一個程式碼段被用來做為方法的引數.
java中沒有直接使用某個方法做為另一個方法的引數的,java使用匿名內部類來模擬這種情況。

比如一個二元函式 f _x,y,x,y是函式內部使用的變數,在只給定 一個引數 x = 7 的情況下, x 已經繫結,但是y還是自由的,這個時候 f(7, y) 就相當於含有一個私有變數(x=7)的函數了。當再給定另外一個變數 y 的值就可對函式完整的求值。所以函式中 有的引數是繫結的,有的引數自由的,這樣的機制稱為閉包。

閉包的價值在於可以作為函式物件或者匿名函式,持有上下文資料,作為第一級物件進行傳遞和儲存。閉包中的部分變數沒有在引用者的作用域內宣告,對於引用者這些變數就是自由變數。

java中能夠儲存方法的變數指的就是普通的物件。Java最常用的閉包實現辦法(內部類+介面)。通俗點講:內部類的方法既能引用宿主的私有變數,又能傳入主動呼叫者的變數(包括 指向物件(該物件可以抽象出介面:自定義回撥函式)的變數),該內部類也可抽象出介面便於擴充套件。內部類的模擬閉包機制還實現了窺內的效果。

由於閉包上下文中有引用指向了內部類的宿主,所以宿主物件在沒有其他引用的情況下也不會被銷燬,只有該閉包中的回撥函式執行完,才會被GC回收。

 [在A作用域中使用的變數x(A一般為主執行緒的方法,主動呼叫者),卻沒有在A作用域中宣告(即在其他作用域中宣告的),對於A作用域來說,x就是一個自由變數],比如fun(x,y){},x和y是函式自己定義的,就不是自由變數,如果x是使用其他函式定義的,就是自由變數

總結:瞭解完閉包之後,我們知道在java1.8中不需要用內部類的方式實現閉包。

Lambda表示式會被編譯器轉換成相應函式式介面的一個例項,它表示式提供了一個上下文環境,既能引用該例項作用域的變數,又可以引用主程式所在作用域的所有變數。這種效果就是閉包,該例項中的變數就是自由變數。

閉包就是一個函式引用另外一個函式的變數,因為變數被引用著所以不會被回收,因此可以用來封裝一個私有變數。這是優點也是缺點,不必要的閉包只會徒增記憶體消耗

http://blog.csdn.net/hnust_xiehonghao/article/details/46326997

根據groovy中的閉包來理解

一個groovy閉包就像一個程式碼塊或者方法指標,他是定義然後執行的一段程式碼,但是他有一些特性:隱含變數,支援自由變數,支援currying 。

我們先來看看一些例子:

1 def clos = { println "hello!" }
2
3 println "Executing the Closure:"
4 clos() //prints "hello!"

在上面的例子中”hello!”是因為呼叫clos()函式才打印出來的,而不是在定義的時候打印出來的。

引數

閉包的引數在->之前列出,比如:

1 def printSum = { a, b -> print a+b }
2 printSum( 57 //prints "12"

如果閉包的引數是少於2個的話,那麼 ->是可以省略的。

Parameter notes

A Closure without -> , i.e. {} , is a Closure with one argument that is implicitly named as ‘it’. (see below for details) In some cases, you need to construct a Closure with zero arguments, e.g. using GString for templating, defining EMC Property etc. You have to explicity define your Closure as { -> } instead of just { }

You can also use varargs as parameters, refer to the Formal Guide for details. A JavaScript-style dynamic args could be simulated, refer to the Informal Guide.

自由變數

閉包能引用在引數列表中沒有列出的變數,這些變數成為自由變數,他們的作用範圍在他們定義的範圍內:

1 def myConst = 5
2 def incByConst = { num -> num + myConst }
3 println incByConst(10// => 15

另外一個例子:

1 def localMethod() {
2 def localVariable = new java.util.Date()
3 return println localVariable }
4 }
5
6 def clos = localMethod()
7
8 println "Executing the Closure:"
9 clos() //prints the date when "localVariable" was defined

隱式變數

it

如果你有一個閉包但是隻有一個引數,那麼你可以省略這個引數,比如:

1 def clos = { print it }
2 clos( "hi there" 

相關推薦

java1.8 lambda表示式 語言程式設計

java1.8出來好久一直沒怎麼關注。這段時間公司的專案資料處理,需要頻繁操作集合,用for遍歷集合做計算,感覺很費勁,而且有大量重複程式碼。可讀性也不高。這時候想到java1.8新特性之一:函數語言程式設計 一、函式式介面 (functional interface)

Java8 Lambda表示式 語言程式設計

什麼是λ表示式 λ表示式本質上是一個匿名方法。讓我們來看下面這個例子: public int add(int x, int y) { return x + y; } 轉成λ表示式後是這個樣子: (int x, int y) -> x + y; 引數型別也可以省略,Jav

java中lambda語言程式設計)一行解決foreach迴圈

首先給大家推薦《精通lambda表示式:java多核程式設計》 這本書詳細介紹了lambda表示式從入門到理解、應用 下面介紹用以前的迴圈方式進行對比,來更加清晰地java函數語言程式設計中foreach的用法 一、以前我們使用的for迴圈 /** * for迴圈

用java語言程式設計——Lambda表示式

函數語言程式設計 很多開發語言都開始支援函數語言程式設計,其中最具備代表性的就是haskell。函數語言程式設計和麵向物件程式設計可以理解為兩大開發陣營。 在函數語言程式設計中,所有的資料都是不可變的,不同的函式之間通過資料流來交換資訊,函式享有跟資料一樣的地位,可以作為引數傳遞給下一個函式

Python學習筆記(十二):lambda表示式語言程式設計

以Mark Lutz著的《Python學習手冊》為教程,每天花1個小時左右時間學習,爭取兩週完成。 --- 寫在前面的話 2013-7-22 21:00 學習筆記 1,lambda的一般形式是關鍵字lambda後面跟一個或多個引數,緊跟一個冒號,以後是一個表示

Lambda表示式語言程式設計探索

Java 8引入流機制和Lambda表示式之後,兩者配合地可謂是天衣無縫,本來想看看Java流庫有什麼東西,可是全是Lambda表示式,暈死,看來得好好了解一下Lambda了! 函數語言程式設計 在文獻2中,作者由Swing中的ActionListener來引入La

Java語言程式設計:初識Lambda表示式

一,Lambda表示式 隨著多核CPU和大資料的流行,為了寫出在多核CPU上執行良好的程式 人們開發出了java.util.concurrent包和很多第三方類庫,試圖將併發抽象化 面對大型資料集合,java還欠缺高效的並行操作,開發者能夠使用java8編寫複雜

Java 8 語言程式設計 Lambda

Lambda表示式 a function (or a subroutine) defined, and possibly called, without being bound to an identifier。 一段帶有輸入引數的可執行語句塊。 在Java 8

java8 語言程式設計基礎--Lambda表示式 note

Lambda表示式稱為閉包(Closure). Lambda表示式是實現函數語言程式設計的基礎。 函數語言程式設計將程式程式碼看做數學中的函式,函式本身作為另一個函式的引數或者返回值,即高階函式。 函數語言程式設計強調函式的計算比指令的執行重要。 和過程化程式設計相比,函數語言程

【怎樣寫程式碼】語言程式設計 -- Lambda表示式(一):引出

如果喜歡這裡的內容,你能夠給我最大的幫助就是轉發,告訴你的朋友,鼓勵他們一起來學習。 If you like the content here, you can give me the greatest help is forwarding, tell you

python day10 python作用域 、lambda表示式(又稱匿名函式) 、 語言程式設計 、 遞迴函式 recursion

目錄: python作用域 、lambda表示式(又稱匿名函式) 、 函數語言程式設計 、 遞迴函式 recursion python作用域: 定義: 作用域也叫名稱空間,是訪問變數時查詢變數名的範圍空間 python的四個作用域LE

python3 lambda表示式語言程式設計

簡單來說,程式設計中提到的 lambda 表示式,通常是在需要一個函式,但是又不想費神去命名一個函式的場合下使用,也就是指匿名函式。其一般有如下幾種使用方式: 1、lambda的一般形式是關鍵字lambda後面跟一個或多個引數,緊跟一個冒號,以後是一個表示式。lambda是

語言程式設計--使用lambda表示式

前面一篇部落格我們已經說到了,lambda表示式允許使用更簡潔的程式碼來建立只有一個抽象方法的介面的例項。現在我們來寫一段java的命令者模式來自己研究下lambda表示式的語法。 這裡重複下命令者

『 Python筆記』 lambda表示式語言程式設計

lambda表示式 lambda用來編寫簡單的函式,而def用來處理更強大的任務。 lambda的一般形式是關鍵字lambda後面跟一個或多個引數,緊跟一個冒號,以後是一個表示式。 lambda是一個表示式而不是一個語句。它能夠出現在Python語法不允許

【怎樣寫程式碼】語言程式設計 -- Lambda表示式(三):LINQ初步

如果喜歡這裡的內容,你能夠給我最大的幫助就是轉發,告訴你的朋友,鼓勵他們一起來學習。 If you like the content here, you can give me the greatest help is forwarding, tell you

【java語言程式設計02】lambda表示式與雙冒號

java lambda表示式 0 總結在前面: lambda表示式是java函數語言程式設計正規化的一個表現形式,將單方法類或介面的實現,直接看成一個可直接定義的函式方法,以更緊湊簡潔形式,提高可讀性,減少程式碼量; Lambda表示式允許您更緊湊地表達單方

語言程式設計/lambda表示式入門

函數語言程式設計/lambda表示式入門 本篇主要講解 lambda表示式的入門,涉及為什麼使用函數語言程式設計,以及jdk8提供的函式式介面 和 介面的預設方法 等等 1.什麼是指令式程式設計 指令式程式設計就是我們去告訴程式如何實現 比如在一堆數字中尋找最小值 int[] nums = {33,

Java8語言程式設計以及Lambda表示式

第一章 認識Java8以及函數語言程式設計 儘管距離Java8釋出已經過去7、8年的時間,但時至今日仍然有許多公司、專案停留在Java7甚至更早的版本。即使已經開始使用Java8的專案,大多數程式設計師也仍然採用“傳統”的編碼方式。 即使是在Java7就已經有了處理異常的新方式——try-with-resou

java8新特性 lambda Stream map(語言程式設計)

1.介面的預設方法 Java 8允許我們給介面新增一個非抽象的方法實現,只需要使用 default關鍵字即可,這個特徵又叫做擴充套件方法 //Formula表示一個設計 計算公式 的介面 public interface Formula { //計算 double calculate

Python(九)語法 語言程式設計(函式作為返回值,lambda

函式作為返回值 高階函式除了可以接受函式作為引數外,還可以把函式作為結果值返回。 我們來實現一個可變引數的求和。通常情況下,求和的函式是這樣定義的: >>> def sum(*args): ... s=0 ... for x in args: ... s=s+x