轉帖|行業資訊|編輯:龔雪|2014-06-09 09:51:07.000|閱讀 873 次
概述:伴隨著Java SE 8的發布一同到來的Lambda表達式帶來一種相對清晰且更為簡潔的方法接口表達方式,同時也給Java Collection庫帶來了相當顯著的改進,從而大大簡化了對Collection的遍歷、過濾以及數據提取流程。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
作為一大飽受詬病的缺陷,Java作為一款編程語言由于太過啰嗦而受到開發者們的抱怨乃至指責,以至于我們不得不編寫大量代碼以保證每一項既定功能切實得以實現。而Lambda表達式的出現在一部分常見情況下解決了這個難題,同時也讓Java在與競爭對手C#的多年纏斗當中占據了一定程度上的優勢地位。
Lambda表達式伴隨著Java SE 8的發布一同到來,就筆者個人而言它也算得上該版本中最值得關注的新增語言特性。Lambda表達式帶來一種相對清晰且更為簡潔的方法接口表達方式,同時也給Java Collection庫帶來了相當顯著的改進,從而大大簡化了對Collection的遍歷、過濾以及數據提取流程。由Lambda表達式所帶來的新型并發特性還提高了Java運行時在多核心環境下的性能表現。
筆者曾經聽到一些程序員表達的擔憂之情,他們懷疑Lambda表達式會給Java的函數編程結構造成影響、進而損害其面向對象屬性。事實上類似的說法早在六、七年之前就曾經在.Net開發領域鬧得沸沸揚揚。歷史經驗告訴我們,盡管存在不同的聲音、C#語言仍然借此實現了毋庸置疑的改進效果。
C#及VB.Net中的Lambda表達式與LINQ
Lambda表達式隨Visual Studio 2008的發布而正式被納入C#與VB.Net,其主要作用在于支持LINQ(即語言集成查詢)。Lambda表達式是一種匿名函數,大家可以利用它創建委托或者表達樹狀范式。在C#當中,要想創建一條Lambda表達式,大家需要在Lambda運算符=>的左側輸入參數(如果有的話),并在另一側輸入表達式或者語句內容。舉例來說,Lambda表達式x=>x * x的意思是指定一個名為x的參數,其返回值為x的平方。在VB.Net方面,我們則可以使用匿名Function或者Sub定義來創建Lambda表達式。
LINQ是一系列函數的統稱,同樣在Visual Studio 2008中與用戶首次見面,它為C#以及Visual Basic語言語法帶來了多項查詢功能。LINQ在對SQL數據庫、XML文檔、ADO.Net數據集(可能由SQL數據庫產生、也可能不是)以及.Net集合、文件與字符串等進行查詢時功效卓著。最后要說的是LINQ to Object,這條術語是指利用LINQ對任意IEnumerable或者IEnumberable<T>集合進行直接查詢。Lambda在基于方法的LINQ查詢當中被作為指向標準查詢運算符方法——例如where——的參數。
LINQ與Lambda表達式已經在C#開發業界得到了廣泛的認同與使用。我期待著Lambda表達式及其應用能夠以同樣的發展軌跡在Java開發業界占據一席之地。
Java中的匿名內部類
Java當中的匿名內部類可以算是通往Lambda表達式發展道路上的一種起步模式或者雛形。大家可以輕松對這些類進行聯機定義且無需為其設定名稱,舉例來說:
JButton testButton = new JButton("Test Button"); testButton.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent ae){ System.out.println("Click Detected by Anon Class"); } });
在以上示例中(來自甲骨文發布的官方教程),被添加到按鈕中的ActionListener是由actionPerformed方法在匿名內部類中進行定義的,而并非利用經過命名的單獨類。雖然這種處理方式能夠略微降低代碼量,但整體而言表達方式依然啰嗦。
只定義單獨一項方法的接口過去被稱為Single Abstract Method(即單獨抽象方法)接口,如今在Java 8中則被更名為函數接口。如我們所見,函數接口與匿名內部類通常經由Lambda表達式加以使用。
Java中的Lambda語法
正如我們之前所說,C#中的Lambda運算符為=>。而在Java中,Lambda運算符則為-〉。(請大家不要抱怨二者之間的差異。如果語法完全保持一致,那么任何開發者都能夠學會使用——這樣開發水平的高低將無從體現。)
與C#中的Lambda表達式類似,Java 8 Lambda表達式當中包含一套參數列表。舉例來說,(int x)-> x * x指定了一個名為x且返回值為x平方的整數參數。如大家所見,Java 8 Lambda表達式擁有類型化特性。幸運的是,當該類型能夠通過上下文進行推斷時,我們就可以將其省略。
請大家思考以下三種Lambda表達式:
(int x, int y) -> x + y () -> 42 (String s) -> { System.out.println(s); }
現在看看之前提到過的ActionListener在利用Lambda表達式進行重新編寫后是什么樣子:
JButton testButton = new JButton("Test Button"); testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listener"));
整個表達過程簡潔多了,對吧?大家應該還會注意到,由于其中的“e”屬于ActionListener的參數,因此它歸于“對象類型”子句、而且其類型也能夠正確推斷得出。
標準函數接口
Java 8中的java.util.function包提供五種標準函數接口類型:
這些還僅僅是起步,因為大家總能對自己的接口加以定義,不過上面幾種函數接口已經足以涵蓋大部分大家平時常見的Lambda表達式使用情況。
Java中的Collection
Lambda表達式有助于簡化Java Collection的使用流程,而且對于在Java 8之前就已經存在的Collection也同樣適用。除此之外,Collection中還加入了大量能夠與Lambda表達式順暢協作的內容,其中包括在每個Iterator及Iterableinterface上被定義的新型forEach()方法。
舉例來說(仍然引用自甲骨文官方教程),我們可以為Personclass定義一個List,并假設其下包含一個age成員:
List<Person> pl = Person.createShortList();
接下來,我們可以定義一個Predicate來選擇列表中的內容:
Predicate<Person> allDrivers = p -> p.getAge() >= 16;
最后,我們能夠對來自該List的選擇內容進行操作:
someClass.doSomething(pl, allDrivers);
經過比較,大家應該會發現Java 8在處理同一項任務時、代碼要比前續版本表現得更為緊湊。
如果我們需要完成一些更為復雜的操作,使用前面提到過的forEach()方法相信能夠達到目的:
pl.forEach( p -> p.printWesternName() );
假設大家希望一次性使用多個Predicate,那么新近登場的filter()方法無疑是最好的幫手——它能夠將Predicate作為參數加以處理,從而使用戶得以把多個方法串聯起來:
pl.stream().filter(search.getCriteria("allPilots")) .forEach(Person::printWesternName);
經過認真考量,大家應該會發現這種串聯化filter在效率上要遠遠優于之前以手動方式為Collection成員編寫循環。不符合前期標準的成員將全部被丟棄,而不再被繼續傳遞到后續filter機制當中。
大家可能還注意到了我們在代碼開頭所使用的stream()方法——我們需要借此來啟用串聯機制。在這里,stream()方法將Collection作為輸入內容,并將java.util.stream.Stream接口作為輸出內容。所謂Stream,代表著一系列能夠作為不同方法串聯基礎的元素。Stream能夠以串行或者并行方式(使用parallelStream方法)付諸執行,這就給進一步提升性能表現帶來了發揮空間。Stream會在使用結束后被自動處理掉。如果大家希望保留這些結果,可以將其復制到其它Collection當中。
我們當然還可以進一步討論aggregate與map等方法,但相信說到這里大家已經對這套新機制擁有了初步概念。
綜上所述,Java 8中的Lambda表達式給該語言帶來了一系列改進。這種新型表達式的出現讓一部分代碼更易于查看及編寫,特別是對于那些能夠以函數形式表達的代碼而言。Lambda表達式還為Java語言帶來更加豐富的表達能力,并使多種操作在運行時當中獲得更為高效的執行效果。通過LINQ與Lambda表達式在.Net開發環境下的表現,可以肯定的是其在為Java帶來諸多改進之外并不會破壞現有面向對象特性。它的加入將使Java語言變得更加豐富、強大與精致。
原文://tech.it168.com/a2014/0505/1619/000001619786_all.shtml
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:慧都控件網