1. 程式人生 > >java8 lambda詳解

java8 lambda詳解

一)輸入引數

在Lambda表示式中,輸入引數是Lambda運算子的左邊部分。它包含引數的數量可以為0、1或者多個。只有當輸入引數為1時,Lambda表示式左邊的一對小括弧才可以省略。輸入引數的數量大於或者等於2時,Lambda表示式左邊的一對小括弧中的多個引數質檢使用逗號(,)分割。

示例1

下面建立一個Lambda表示式,它的輸入引數的數量為0.該表示式將顯示“This is a Lambda expression”字串。

  1. ()=>Console.WriteLine("This is a Lambda expression.");  

分析2

由於上述Lambda表示式的輸入引數的數量為0,因此,該Lambda表示式的左邊部分的一對小括弧不能被省略。

示例2

下面建立一個Lambda表示式,它的輸入引數包含一個引數:m。該表示式將計算m引數與2的乘積。

  1. m=>m*2;  

分析2

上述Lambda表示式的輸入引數省略了一對小括弧,它與“(m)=>m*2”Lambda表示式是等效的。

示例3

下面建立一個Lambda表示式,它的輸入引數包含兩個引數:m和n。該表示式將計算m和n引數的乘積。

  1. (m,n)=>m*n;  


(二)表示式或語句塊

多個Lambda表示式可以構成Lambda語句塊。語句塊可以放到運算子的右邊,作為Lambda的主體。根據主題不同,Lambda表示式可以分為表示式Lambda和語句Lambda。語句塊中可以包含多條語句,並且可以包含迴圈、方法呼叫和if語句等。

示例1

下面建立一個Lambda表示式,它的右邊部分是一個表示式。該表示式計算m引數的平方值。

  1. m=>m*n;  

分析1

如果Lambda表示式的右邊部分是一個語句塊,那麼該語句塊必須被"{"和"}"包圍。

示例2

下面建立一個Lambda表示式,它的輸入引數包括兩個引數:m和n。該表示式的右邊包含2個表示式;第一個表示式計算m和n引數的乘積,結果儲存為result變數;第二個表示式顯示result變數的值。

  1. (m,n)=>{int result=m*n; Console.WriteLine(result);}  

分析2

上述Lambda表示式的右邊部分包含2個表示式,因此,該表示式的右邊部分必須被"{"和"}"包圍。

(三)查詢表示式

查詢表示式是一種使用查詢語法表示的表示式,它用於查詢和轉換來自任意支援LINQ的資料來源中的資料。查詢表示式使用許多常見的C#語言構造,易讀簡潔,容易掌握。它由一組類似於SQL或XQuery的宣告性語法編寫的子句組成。每一個子句可以包含一個或多個C#表示式。這些C#表示式本身也可能是查詢表示式或包含查詢表示式。

●查詢表示式必須以from子句開頭,以select或group子句結束。第一個from子句和最後一個select子句或group子句之間,可以包含一個活多個where子句、let子句、join子   句、orderby子句和group子句,甚至還可以是from子句。它包括8個基本子句,具體說明如下所示。

●from子句:指定查詢操作的資料來源和範圍變數。

●select子句:指定查詢結果的型別和表現形式。

●where子句:指定篩選元素的邏輯條件。

●let子句:引入用來臨時儲存查詢表示式中的字表達式結果的範圍變數。

●orderby子句:對查詢結果進行排序操作,包括升序和降序。

●group子句:對查詢結果進行分組。

●into子句:提供一個臨時識別符號。join子句、group子句或select子句可以通過該識別符號引用查詢操作中的中堅結果。

●join子句:連線多個用於查詢操作的資料來源。

示例1

下面建立一個查詢表示式query,該查詢表示式查詢arr陣列中的每一個元素。

int[]arr =new int[]{0,1,2,3,4,5,6,7,8,9};

分析1

  1. var query1=from n in arr  
  2.                 select n;  
示例2

下面建立一個查詢表示式query2.該查詢表示式查詢arr陣列中大於6的元素。

  1. int[] arr =newint[]{0,1,2,3,4,5,6,7,8,9};  
  2. var query2=from n in arr  
  3.               where n >6  
  4.               select n;  

分析2

變數只是儲存查詢操作,而不是查詢的結果。當查詢表示式執行查詢操作時,才會計算該查詢表示式的結果。以上兩個變數的型別都屬於集合型別。

(四)from子句

from子句用來指定查詢表示式的資料來源和範圍變數。它是查詢表示式的必有部分,並且它出現在最開始。資料來源不但可以包括查詢本身的資料來源,而且還可以包括子查詢的資料來源。範圍變數用來表示資料來源序列中的每一個元素。

注意:from子句指定的資料來源的型別必須為IEnumerable,IEnumerable<T>或一種派生型別。

示例1

下面建立一個查詢表示式query。該查詢表示式查詢arr陣列中的每一個元素。在query查詢表示式中,arr陣列為資料來源,n為範圍變數。n範圍變數的型別arr資料來源的元素型別。

分析1
  1. int[] arr =newint[] {0,1,2,3,4,5,67,8,9};  
  2. var query =from n in arr  
  3.  select n;  

下面我們來學習資料來源和包含不同的from子句查詢表示式。

資料來源:指定資料的來源,它的形式可以為靜態陣列、動態陣列(Arraylist)、集合、資料集(DataSet)、資料表、MML片段、MML檔案等。

如果資料來源實現了IEnumerable<T>介面,那麼編譯器可以推斷範圍變數的型別為其元素型別。例如:資料來源的型別為IEnumerable<UserInfo>,那麼可以推斷出範圍 變數的型別為UseInfo。

示例2

下面建立一個查詢表示式query。該查詢表示式查詢list反省陣列中的每一個元素。在query查詢表示式中,list反省陣列為資料來源。u為範圍變數。u範圍變數的型別為list資料來源的元素型別(UserInfo)。

分析2

  1. List<UserInfo> list=...  
  2. var query =from u in list  
  3.            select u;  

如果當資料來源是非泛型IEnumerable型別(如ArrayList等)時,需要顯示指定範圍變數的型別。

示例3

下面建立一個查詢表示式query。該查詢表示式查詢list陣列中的每一個元素。在query查詢表示式中,list陣列為資料來源,u為範圍變數。u範圍變數的型別被指定為list資料來源的元素型別(UserInfo)。

分析3

  1. ArrayList list =new ArrayList();  
  2. list.Add(...);  
  3. ...  
  4. var query =from UserInfo u in list  
  5.     select u;  
包含單個from子句的查詢表示式

在查詢表示式中,from子句至少有一個。當from子句只有一個時,構成的查詢表示式被稱為包含單個from子句的查詢表示式。一般的,包含單個from子句的查詢表示式只包含一個數據源。

示例4

下面建立一個查詢表示式query。該查詢表示式查詢arr陣列中的每一個元素,它就是一個包含單個from子句的查詢表示式。

分析4

  1. int[] arr =newint[]{0,1,12,3,4,5,6,7,8,9};  
  2. var query =from n in arr  
  3.        select n;  

包含多個from子句的查詢表示式

在查詢表示式中,當from子句有兩個或兩個以上時,構成的查詢表示式被稱為包含多個from子句的查詢表示式。

示例5

下面建立一個查詢表示式query。該查詢表示式包含兩個from子句,他們分別查詢兩個獨立的資料來源;arr1陣列和arr2陣列。最後,使用select子句計算當前元素的和。

分析5

  1. int[] arr1= newint[] {0,1,2,3,4,5,6,7,8,9};  
  2. int[] arr2=newint[] {0,1,2,3,4,5,6,7,8,9};  
  3. var query =from a in arr1  
  4.        from b in arr2  
  5.        select a +b;  

包含符合from子句的查詢表示式

在查詢表示式中,有可能查詢表示式的資料來源中的每一個元素本身也作為該查詢表示式的資料來源。那麼要查詢資料來源中的每一個元素中的元素,則需要使用符合from子句。符合from子句類似於巢狀的foreach語句。

示例6

下面建立一個名稱為Test的類,該類包含兩個欄位:Name和AliasName。其中,Name欄位的型別為string,AliasName欄位的型別為string型別列表。因此,它也可以作為子查詢表示式的資料來源。

分析6

  1. publicclass Test  
  2. {  
  3.     Public string Name;  
  4.     Public List<string> AliasName;  
  5. }  

示例7

下面建立一個查詢表示式query。該查詢表示式包含了一個符合from子句:第一個from子句查詢list泛型集合;第二個from子句查詢list集合中元素的AliasName欄位,為第一個from子句的子查詢。最後,使用select子句將u變數的Name屬性的值和name變數的值拼接為一個字串。

分析7

  1. List<MUserInfo> list =...  
  2. var query =from u in list  
  3.      from name in u.AliasName  
  4. select u.Name+name;  


(五)select子句

select子句用來指定將在執行查詢時產生的值的型別。查詢表示式必須以select子句或group子句結束。

示例1

下面建立一個查詢表示式query。該查詢表示式查詢arr陣列中的每一個元素。

分析1

  1. int[] arr =newint[] {0,1,2,3,4,5,6,7,8,9};  
  2. var query =from n in arr  
  3.        select n;  

示例2

下面建立一個查詢表示式query。該查詢表示式查詢arr陣列中的每一個元素和10的乘積。

  1. int[] arr =newint[] {0,1,2,3,4,5,6,7,8,9};  
  2. var query =from n in arr   
  3.     select n*10;  

分析2

select子句中的“n*10”表示式決定了查詢結果的表現形式,即計算每一個元素和10的乘積。

示例3

下面建立一個查詢表示式query。該查詢表示式查詢arr陣列中的每一個元素,查詢結果是一個物件的集合物件包含兩個屬性:ID和Name,它在select子句中由匿名物件初始化器建立。每一個物件的ID屬性的值是當前元素的值、Name屬性的值為元素的值的字串的表現形式。

分析3

  1. int[] arr =newint[]{0,1,2,3,4,5,6,7,8,9};  
  2. var query =from n in arr   
  3.     select new
  4.     {  
  5.          ID=n,  
  6.          Name =n.ToString()  
  7.     };  


(六)where子句

where子句用來指導將在查詢表示式中返回資料來源中的哪些元素。它將一個布林條件應用於資料來源中的每個元素,並返回指定條件的元素。查詢表示式可以包含一個或多個where子句。

示例1

下面建立一個查詢表示式query。該查詢表示式從arr陣列中查詢小於3的元素

  1. int[] arr =newint[] {0,1,2,3,4,5,6,7,8,9};  
  2. var query =from n in arr  
  3.         where n <3  
  4.         select n;  

分析1

上述where子句只包含一個布林表示式“n<3”,該表示式將篩選小於3的元素。

在一個where子句中,也可以包含多個布林表示式,各個表示式直接使用邏輯運算子(如&&和||)分隔。

示例2

下面建立一個查詢表示式query。該查詢表示式從arr陣列中查詢大於3且小於6的元素。

  1. int[] arr =newint[]{0,1,2,3,4,5,6,7,8,9};  
  2. var query =from n in arr  
  3.               where n >3 && n<6  
  4.               select n;  

分析2

上述where子句包含兩個布林表示式"n>3"和"n<6",它們共同指定將篩選大於3且小於6的元素。這兩個布林表示式使用&&運算子連結,即計算這兩個布林表示式的邏輯與。

where子句不但可以包含布林表示式,而且還可以包含返回布林值的方法。

示例3

下面建立一個查詢表示式query.該查詢表示式從arr陣列中查詢為偶數的元素。

  1. int

    相關推薦

    java8 lambda

    一)輸入引數在Lambda表示式中,輸入引數是Lambda運算子的左邊部分。它包含引數的數量可以為0、1或者多個。只有當輸入引數為1時,Lambda表示式左邊的一對小括弧才可以省略。輸入引數的數量大於或者等於2時,Lambda表示式左邊的一對小括弧中的多個引數質檢使用逗號(,

    java8 Stream

    Stream組成 在傳統Java程式設計,或者說是類C語言程式設計中,我們如何操作一個數組資料呢?或者更泛化的講,我們如何操作一個“集合”(Collection)資料呢?在Java中我們利用java.util包裡的各種資料結構封裝,來很好的表示了陣列(Array)、

    Java8 HashMap

    Java8 HashMap Java8 對 HashMap 進行了一些修改,最大的不同就是利用了紅黑樹,所以其由 陣列+連結串列+紅黑樹 組成。 根據 Java7 HashMap 的介紹,我們知道,查詢的時候,根據 hash 值我們能夠快速定位到陣列的具

    Java8 ConcurrentHashMap

    Java8 ConcurrentHashMap Java7 中實現的 ConcurrentHashMap 說實話還是比較複雜的,Java8 對 ConcurrentHashMap 進行了比較大的改動。建議讀者可以參考 Java8 中 HashMap 相對於

    Java8 Optional

    在Java8中新增了一個Optional類,官方描述是該類是一個容器物件,其中可能包含一個空或非空的值。如果存在一個值,isPresent()將返回true,get()將返回該值。 錯誤使用姿勢 簡單的根據描述,我們認為Optional可以幫我們解決NP

    C++lambda~讀書筆記

    lambda表示式: [capture_block](parameters) mutable exception_specification->return_type{ body }lambda表示式包含以下部分: 捕捉塊(catpure block): 指定如何

    [二] java8 函式式介面 函式介面 lambda表示式 匿名函式 方法引用使用含義 函式式介面例項 如何定義函式式介面

    package java.lang; import java.lang.annotation.*; /** * An informative annotation type used to indicate that an interface * type declaration is inten

    Java8新特性Stream API與Lambda表示式(1)

    1 為什麼需要Stream與Lambda表示式? 1.1  為什麼需要Stream Stream作為 Java 8 的一大亮點,它與 java.io 包裡的 InputStream 和 OutputStream 是完全不同的概念。它也不同於 StAX 對 XML 解析的 S

    Lambda表示式--Java8的新功能案例(2) Lambda表示式的方法引用

    Lambda表示式與內部類相比有很多限制,比如只能為函式式介面建立例項,但是Lambda表示式大大簡化了程式碼的書寫。 Lambda表示式的方法引用主要分為下面幾類: 1.引用類方法 2.引用特定物件的例項方法 3.引用某類物件的例項方法 4.引用構造方法 下面通過幾個例項

    Java8 Lambda表示式手冊及例項

    先販賣一下焦慮,Java8發於2014年3月18日,距離現在已經快6年了,如果你對Java8的新特性還沒有應用,甚至還一無所知,那你真得關注公眾號“程式新視界”,好好系列的學習一下Java8的新特性。Lambda表示式已經在新框架中普通使用了,如果你對Lambda還一無所知,真得認真學習一下本篇文章了。 現在

    Java8學習筆記(五)--Stream API[轉]

    有效 編程效率 實時處理 phaser 綜合 files -- bin 並發模式 為什麽要使用StreamStream 作為 Java 8 的一大亮點,它與 java.io 包裏的 InputStream 和 OutputStream 是完全不同的概念。它也不同於 StAX

    【轉】Lambda表達式

    執行 pan mpi 新增 turn sum 下層 裏的 泛型類 前言 1、天真熱,程序員活著不易,星期天,也要頂著火辣辣的太陽,總結這些東西。 2、誇誇lambda吧:簡化了匿名委托的使用,讓你讓代碼更加簡潔,優雅。據說它是微軟自c#1

    Java8新特性之Stream

           最近在公司的專案中常用Stream結合Lambda表示式來操作集合,使得專案整體程式碼簡潔和整齊;並且上一章也講了一些關於Stream的常用操作,比如:map()、filter()、concat()、reduce()、max()、min()、

    Java8新特性之Stream

    寫了Lambda表示式的部落格,怎麼能少了對Stream的學習呢!接下來就將我所理解的Stream分享給大家,歡迎指出不足之處... 一、為什麼要使用Stream?Stream是什麼?在Java中該怎麼用呢?        (1)為什麼要使用Str

    lambda表示式入門

    轉自 2018-03-02 Sevenvidia 碼農翻身 1、什麼是Lambda? 我們知道,對於一個Java變數,我們可以賦給其一個“值”。   如果你想把“一塊程式碼”賦給一個Java變數,應該怎麼做呢?  比如,我想把右邊那塊程式碼,賦給一個叫做aBlo

    JAVA8如何用Optional解決NPE問題

    引用處: JAVA8如何妙用Optional解決NPE問題詳解 引言 NPE(NullPointerException)是除錯程式最常見的異常。google一下有很多關於方法到底應該返回null還是new一個空物件的討論。 在文章的開頭,先說下NPE問題,NPE問題就是,我們在開

    JAVA8新特性

    JAVA8 十大新特性詳解 前言: Java 8 已經發布很久了,很多報道表明Java 8 是一次重大的版本升級。在Java Code Geeks上已經有很多介紹Java 8新特性的文章,

    Java 8 Lambda表示式使用

    1 引言 在 Java 8 以前,若我們想要把某些功能傳遞給某些方法,總要去寫匿名類。以前註冊事件監聽器的寫法與下面的示例程式碼就很像: manager.addScheduleListener(new ScheduleListener() { @Override pu

    java8流(Stream API)使用:篩選、切片、對映、查詢、匹配和歸約等流操作

    上一篇中介紹了集合操作的痛點並發現集合操作的這些痛點在java8流API面前基本都不是事,隨後引出了流的定義並介紹了流操作的型別、特徵,以及使用流的基本步驟,本篇將逐一介紹Stream Api中各種流操作及一些特殊流的使用。 用謂詞篩選 關於篩選在該系列前面文章中已經出現