Java8 lambda表達式

2020-12-03 計算機java編程

java8中最大的變化就是引入了lambda表達式,一種緊湊的傳遞行為的方式,這也是本書剩下部分所要討論的內容,讓我們進入其中吧。

編寫第一個lambda表達式

swing是一個平臺無關的gui庫,在該庫中,有很多常見的習慣,比如為了知道用戶點點擊了什麼,註冊一個事件監聽器,這個事件監聽器可以執行一些操作響應用戶的輸入。

在該例子中,我們創建了一個對象實現了ActionListener接口,該接口只有一個方法actionPerformed(),當用戶點擊了按鈕之後,這個方法會被調用,該匿名內部類提供了該方法的實現。

匿名內部類是為了讓java程式設計師傳遞行為和傳遞數據一樣容易,不幸的是,他們並不容易,為了調用處理邏輯的代碼仍然有四行模板代碼,重複的模板代碼並不是唯一的問題,這種代碼也難以閱讀,我們並不想傳遞一個對象,而僅僅只需要傳遞某種行為,在java8中我們可以寫得更簡潔

不同於傳遞一個實現某個接口的對象,我們傳遞了一段沒有命名函數的代碼,

event

是參數,同匿名內部類的參數一樣,

->

將參數和lambda表達式的內容體分開。同匿名內部類做法另外一種不同就是,我們申明變量的方式,之前,我們需要顯示申明類型ActionEvent,在該例中,我們不需要提供類型,編譯也能通過,在這背後發生的是javac從上下文獲取event類型,此處是從addActionListener籤名中獲取,這意味著你不需要顯示申明其類型,我們之後會更加詳細討論這種設計,首先讓我們看看編寫lambda表達式幾種不同的方法。

如何在正確的場合使用lambda表達式?下面有幾個使用lambda表達式的例子

①展示了在沒有參數的情況下如何使用lambda,可以使用一對空的小括號來表示沒有參數,這是一個實現了Runnable的lambda的表達式,該接口只有一個方法run(),該方法不接受任何參數,且返回void.

②展示了只有一個參數的lambda的表達式。不同於只包含一條表達式的lambda。

③包含了一個代碼塊,包含在一個大括號中,代碼塊同平常的方法類似,在結束之前可以返回結果或者拋出異常,

④包含了多個參數,這種情況下有必要考慮如何閱讀這條表達式,這行代碼沒有相加兩個數,它創建了一個函數相加兩個數,add這個變量並不是兩個數的和,而是一個相加兩個數的函數。

⑤目前為止,所有的lambda表達式參數類型都是由編譯器確定,這非常棒,但是有些時候我們需要明確參數類型。

上述所有表達式都表明lambda表達式依賴於上下文,由編譯器去判斷,這種做法也不完全新創的,在example2-4中數組的初始化依賴於上下文環境,還有null,只有把它分配的時候才知道其類型。

Using Values

你以往使用匿名內部類的時候,你可能遇到這種情況,在內部類中你想使用外部的變量,需要把外部變量申明為final類型,變量申明為final意味著不能將該變量指向其他對象。

在java8中,這種限制有所放鬆,可以引用非final的參數,雖然沒有申明為final類型,但是必須當做final類型看待,不能去改變其所指的對象,否則會報錯。

如果多次為一個變量賦值,並且單算在lambda表達式中進行引用,那麼會得到一個變異錯誤。

這也是為什麼人們把lambda表達式當做閉包看待,在程式語言的爭論中,有許多關於java是否有閉包的爭論,因為其只能引用final變量,為了避免這一個無端的爭論,我在本書中將他們稱之為lambda表達式。但是無論我如何稱呼他們,我已經提到過lambda表達式是靜態類型的,因此讓我們研究表達式本身:他們稱之為函數式接口。

函數式接口

函數式接口是指的只有一個抽象方法的接口,被當做是lambda表達式的一種類型使用。在java中,所有的參數都有類型,如果我們傳入3到一個方法中,這個參數是int類型,那麼lambda是什麼類型的呢?

類型討論?

某些情況下,需要提供確切的類型標誌,我的建議是你和你的團隊怎麼易讀怎麼做。有的時候不標明類型讓其看起來更加簡潔,有時候加上類型標誌讓其更加明顯。我發現,起初加上類型可能看起來很有用,但是之後可能你只會在必要的時候才會加上,本章將會提供幾個原則讓你很容易辨別出是否必要加上。

類型的討論其實是java7類型討論的延續。

對於變量oldWordCount我們明確指明了泛型的類型,但是diamonWordCounts使用了diamond operator,泛型類型並沒有指出,編譯器會指定其類型。如果你直接傳遞一個構造函數到方法中,編譯器也能指出泛型類型,同樣的java7允許空出構造函數的泛型,java8允許lambda表達式的參數類型。其實沒有什麼魔法,java編譯器在lambda表達式上下文中尋找參數確定的類型。讓我們通過幾個例子更加深入討論。在下面兩種情況下,我們傳入一個參數到一個函數接口中,因此我們很容易確定兩者的區別。

第一個例子:

不同於之前的ActionListener示例,Predicate是一個有返回值的lambda表達式,這裡表達式的內容為x > 5,表達式的值作為lambda表達式的返回值。我們可以看到Predicate有一個泛型參數,上一個表達式中我們傳入一個int值,java編譯器會檢測返回值是否為一個boolean值。

讓我們看看另外一個更加複雜的例子:

BinaryOperator接口

這個接口有兩個參數以及一個返回值,兩個參數類型相同,在實例中我們使用的參數類型為Long類型,但是如果不提供足夠的信息編譯器就會返回一個變異錯誤,例如在下面的一個表達式中就會拋出變異錯誤

總結:

1.lambda表達式沒有命名,用來像傳遞數據一樣傳遞操作。2.函數接口指的是只有一個抽象方法的接口,被當做是lambda表達式的類型。

相關焦點

  • Java8 lambda表達式語法
    本文是該系列的第一篇,主要介紹Java8對屌絲碼農最有吸引力的一個特性—lambda表達式。java8的安裝工欲善其器必先利其器,首先安裝JDK8。過程省略,大家應該都可以自己搞定。但是有一點這裡強調一下(Windows系統):目前我們工作的版本一般是java 6或者java 7,所以很多人安裝java8基本都是學習為主。這樣就在自己的機器上會存在多版本的JDK。
  • Java中Lambda表達式的5種不同語法
    (arr, (String m, String n) -> Integer.compare(m.length(), n.length()));System.out.println(Arrays.toString(arr));lambda表達式的標準語法包括以下內容:
  • Python中的Lambda表達式
    Lambda表達式當我們需要做一些簡單的事情並且更希望快速完成工作而不是正式命名函數時,Lambda表達式是理想的選擇。Lambda表達式也稱為匿名函數。Python中的Lambda表達式是聲明小型匿名函數的一種簡短方式(沒有必要為Lambda函數提供名稱)。
  • 大家都在說的「Lambda 表達式」到底是什麼?
    自從java8中引入了Lambda表達式之後,使用的人也越來越多了,這篇文章我們就來看看什麼是Lambda表達式。廢話少說,先看定義!01定義Lambda表達式也被稱為箭頭函數,匿名函數,閉包Lambda表達式體現的是輕量級函數式編程思想『->』符號式Lambda表達式核心操作符號,符號左側是操作參數,符號右側是操作表達式1、在定義中有一個比較重要的詞就是「函數式編程」現在「
  • Python匿名函數:Lambda表達式
    我們以一張圖形進入主題:從圖中我們可以看出lambda表達式幾點特徵:簡潔性,符合了Python的一貫宗旨;起到了函數的作用,但未顯示函數名稱,這就是匿名函數;接著我們嘗試用lambda表達式來實現上述函數功能:# labmda表達式psum = lambda a,b,c:a + b + cprint(psum) # 驗證是否生成一個新對象
  • Lambda表達式在Python事件中的運用
    本篇筆記內容:Lambda表達式詳解Lambda表達式在事件中的應用【1】Lambda表達式詳解lambda 表達式定義的是一個匿名函數,只適合簡單輸入參數,簡單計算返回結果,不適合功能複雜情況。lambda 定義的匿名函數也有輸入、也有輸出,只是沒有名字。語法格式如下:lambda 參數值列表:表達式其中,參數值列表即為輸入,表達式計算的結構即為輸出。看一個案例:求三個數的和。
  • Python每天一分鐘:lambda表達式 (匿名函數)及用法詳解
    lambda表達式介紹python中有一種靈活,便捷的且具有函數功能的表達式:lambda表達式!lambda 表達式可以用來替換局部函數(感興趣的讀者可以自行查閱「局部函數」),下面為大家演示lambda表達式的具體用法。
  • Python學習第40課-Lambda表達式創建匿名函數
    Python中可以使用Lambda表達式來創建匿名函數。lambda表達式用來創建匿名函數,那麼我們也可以把lambda表達式叫做lambda函數。●Lambda函數的特點lambda函數只需要寫一行代碼,函數體比用def定義的函數體簡單。lambda函數有自己的命名空間,且不能訪問自己命名空間之外或全局命名空間裡的參數。
  • 「數據清洗」lambda表達式配合使用的四種函數
    標籤:數據清洗、pythonlambda表達式配合使用的四種函數一、什麼是lambda表達式基本特性使用方法filter函數map函數sorted函數reduce函數總結什麼是lambda表達式>lambda 表達式是一個匿名函數,lambda表達式基於數學中的λ演算得名,直接對應於其中的lambda抽象,是一個匿名函數,即沒有函數名的函數。
  • CSharp 基礎知識系列- 6 Lambda表達式和Linq簡單介紹
    嗯,簡單來講就是匿名函數,我們不聲明方法名,只寫一個方法體,這個方法體就是lambda表達式1. lambda表達式1.1 如何寫一個lambda表達式首先,在寫lambda表達式之前,需要先了解兩個特殊的類型:Func和Action。這是兩個委託,這裡先不急著了解什麼是委託,可以把它們當做一種名稱規範就行,它們都可以表示一個方法。
  • 三種基本用法、五種應用場景,理清C++11新特性:Lambda表達式
    lambda表達式是指能夠捕獲作用域中的變量的無名函數對象,狹義的理解,就是匿名函數。無論是在項目中,還是在開源網站,總是能夠看到lambda的身影。為了能夠輕鬆閱讀代碼,進而熟練地使用,本文首先將講解lambda表達式的基本語法、三種基本用法,然後介紹五種實際的應用場景,最有總結說明lambda表達式的作用。
  • 詳解Java表達式與運算符
    在java語言中,定義常量的語法如下:final 數據類型 常量名稱 = 值;其中,final是Java關鍵字,數據類型可以是Java語言支持的任何數據類型。表達式的計算結果一般為數值,如果表達式是一個關係表達式或邏輯表達式,表達式會返回一個布爾值,即真或假。根據運算符的不同,可以把表達式分為賦值表達式、算術表達式、關係表達式和邏輯表達式。賦值表達式用於把等號右邊的操作數賦值給等號左邊的變量;算術表達式用於數值運算;關係表達式用於條件判斷;邏輯表達式用於邏輯操作。
  • Java Lambda表達式的3種簡寫方式
    使用 Lambda 表達式是為了簡化程序代碼,Lambda 表達式本身也提供了多種簡化形式,這些簡化形式雖然簡化了代碼,但客觀上使得代碼可讀性變差
  • 給JAVA程式設計師的正則表達式一課
    正則基礎正則表達式(Regex,簡稱RE)是一種根據字符串集中的每個字符串的共同特徵來描述字符串集的方法。可用於搜索,編輯或處理文本和數據。簡單來說,正則表達式是幫助我們根據特定格式驗證或匹配字符串的方式。可以類比資料庫的SQL語言,sql是搜索數據,RE是搜索字符串。正則表達式和SQL語言是開發界的兩個偉大發明。
  • python入門基礎之lambda匿名函數詳解
    一個完整的 lambda"語句"代表了一個表達式,這個表達式的定義體必須和聲明放在同一行。這應該是lambda與def兩者最大的區別。lambda是一個表達式,而不是一個語句(lambda is an expression, not a statement.
  • Python面試題推薦:什麼是lambda函數?
    定義lambda函數的形式如下:labmda 參數:表達式lambda函數默認返回表達式的值。你也可以將其賦值給一個變量。lambda函數可以接受任意個參數,包括可選參數,但是表達式只有一個:>>> g = lambda x, y: x*y>>> g(3,4)12>>> g = lambda x, y=0,
  • lambda匿名函數都自嘆不如
    lambda表達式在學習Python的過程中,很多人常常對lambda表達式的語法感到困惑,什麼是lambda?lambda表達式怎麼用,什麼時候該用lambda?請看下去,下面內容將為你介紹。Python中的lambda是用來創建匿名函數,它是一個表達式,但函數體比def簡單,它的語法如下:語法參數中,arg為入口參數,expression為函數體,用函數表達則如下圖所示:用學習函數的方式來學習lambda表達式就非常容易理解了,在這裡lambda簡化了函數定義的書寫形式,使得代碼更簡潔。
  • Python小白學習記錄-匿名函數lambda
    匿名函數就是不需要通過def定義及顯示地指定函數名的函數匿名函數的特性(1)匿名函數只能有一個表達式,不用寫return,返回值就是該表達式的結果。lambda表示這是一個匿名函數>(2)匿名函數已reduce函數結合隊列中數值相乘(3)匿名函數與filter過濾器的結合,lambda
  • 跟我學java編程—Java邏輯運算符
    第四條語句邏輯與運算符「&&」連接了2個條件表達式,分別是c > a和c < b,如果這兩個表達式計算結果都為真,則bJudge為真,否則bJudge為false。此時bJudge的值為true。該運算符還有一個特點,當左側的條件表達式或布爾變量為假時,則直接返回結果false,不再執行運算符右側的表達式或布爾變量。
  • 跟我學java編程—認識java語言的字符類型
    例如:計算數值表達式時,需要存儲運算符,這時需要一種可以存儲單個字符數據的數據類型。Java語言提供了一種char數據類型,可以滿足存儲單個字符的需要。Java語言中,char佔2個字節的存儲空間,即可以存儲英文字符,也可以存儲單個漢字,一個漢字編碼也佔2個字節的存儲空間。