Java 8 Lambda運算式探險

來源:互聯網
上載者:User

為什嗎?
   我們為什麼需要Lambda運算式
   主要有三個原因:
   > 更加緊湊的代碼
     比如Java中現有的匿名內部類以及監聽器(listeners)和事件處理器(handlers)都顯得很冗長
   > 修改方法的能力(我個人理解為代碼注入,或者有點類似JavaScript中傳一個回呼函數給另外一個函數)
     比如Collection介面的contains方法,若且唯若傳入的元素真正包含在集合中,才返回true。而假如我們想對一個字串集合,傳入一個字串,只要這個字串出現在集合中(忽略大小寫)就返回true。
     簡單地說,我們想要的是傳入“一些我們自己的代碼”到已有的方法中,已有的方法將會執行我們傳入的代碼。Lambda運算式能很好地支援這點
   > 更好地支援多核處理
     例如,通過Java 8新增的Lambda運算式,我們可以很方便地並行操作大集合,充分發揮多核CPU的潛能。
     平行處理函數如filter、map和reduce。

 

怎麼做?
   執行個體1 FileFilter

File dir = new File("/an/dir/");   FileFilter directoryFilter = new FileFilter() {      public boolean accept(File file) {         return file.isDirectory();      }};

   通過Lambda運算式這段代碼可以簡化為如下:

File dir = new File("/an/dir/");FileFilter directoryFilter = (File f) -> f.isDirectory();File[] dirs = dir.listFiles(directoryFilter);

   進一步簡化:

File dir = new File("/an/dir/");File[] dirs = dir.listFiles((File f) -> f.isDirectory());

   Lambda運算式使得代碼可讀性增強了。我承認我開始學習Java的時候對那個匿名內部類感到很困擾,而現在Lambda運算式讓這一切看起來都很自然(尤其是有.NET背景的童鞋會發現這個跟.NET中的Lambda運算式好像)


   Lambda運算式利用了類型推斷(type inference)技術:

編譯器知道FileFilter只有一個方法accept(),所以accept()方法肯定對應(File f) -> f.isDirectory()
而且accept()方法只有一個File類型的參數,所以(File f) -> f.isDirectory()中的File f就是這個參數了,
.NET把類型推斷做得更絕,如果上面用.NET Lambda運算式寫法的話是這樣的:   File[] dirs = dir.ListFiles(f => f.isDirectory());即壓根就不需要出現File類型指示。

   執行個體2 Event Handler

Button bt = new Button();   bt.addActionListener(new ActionListener() {      public void actionPerformed(ActionEvent e) {         ui.showSomething();      }});

   使用Lambda運算式後:

Button bt = new Button();ActionListener listener = event -> { ui.showSomething(); };bt.addActionListener(listener);

   進一步簡化: 

Button bt = new Button();bt.addActionListener(event -> { ui.showSomething(); });

 

外迴圈、內迴圈和Map、Reduce、Filter
   一直到現在,處理Java集合的標準做法是採用外迴圈。比如:

List<String> list = new ArrayList<String>();list.add("hello");list.add("world");for(int item: list) {   // 處理item}

   還有迭代器迴圈,它們都是外迴圈,並且都是順序處理(sequential handling)。順序特性也常常引發ConcurrentModificationException,只要我們嘗試著並發修改集合。
   Lambda運算式提供了內迴圈機制。


   我們工作中可能經常面臨下面的需求:

> 過濾掉一個集合中不合格元素得到一個新集合> 對集合中的每個元素進行某種轉換,並且對轉換後的集合進行處理> 統計整個集合的某個屬性,比如統計集合元素值的總和或平均值

   這些任務即filter、map和reduce,他們的共同特點是:
   需要對集合中的每個元素運行一小段相同的代碼。


   傳統的實現這些任務的代碼讓人感到很乏味,幸運的是Java 8提供了完成這些任務的更簡潔的方案,當然還是利用Lambda運算式,但也引入了一個新的類庫java.util.functions,包含Predicate、Mapper和Block。


   Java 8中,一個Predicate(謂詞)是這樣一個方法:它根據變數的值進行評估(evaluate),返回true或false。


   比如下面:

List<String> list = getMyStrings();for(String myString: list) {   if(myString.contains(possible)) {       System.out.println(myString + " contains " + possible);   }}

   使用Predicate和Filter後得到下面代碼:

List<String> list = getMyStrings();Predicate<String> matched = s -> s.equalsIgnoreCase(possible);list.filter(matched);

   進一步簡化:

List<String> list = getMyStrings();list.filter(s -> s.equalsIgnoreCase(possible));

 

Lambda運算式文法規則
   到目前為止Java 8中的Lambda運算式文法規則還沒有完全確定。

   但這裡簡單介紹下:

   對於前面的:

File dir = new File("/an/dir/");File[] dirs = dir.listFiles((File f) -> f.isDirectory());

   accept()方法返回布爾值,這種情況f.isDirectory()顯然也得是布爾值。這很簡單。
   而對於:

Button bt = new Button();bt.addActionListener(event -> { ui.showSomething(); });

   actionPerformed()方法的傳回型別是void,所以需要特殊處理,即在ui.showSomething();左右加上花括弧。(想象下不加會怎麼樣?如果不加的話,若showSomething()方法傳回值是整數類型,那麼就意味著actionPerformed()返回整數類型,顯然不是,所以必須加花括弧用來標記)。
   如果Lambda運算式主體部分包含多條語句,也必須用花括弧,並且return語句不能省。


   比如下面這個:

File dir = new File("/an/dir/");File[] dirs = dir.listFiles((File f) ->  {                                             System.out.println("Log:...");                                            return f.isDirectory();                                          });

 

參考自:http://www.oraclejavamagazine-digital.com/javamagazine/20121112?sub_id=hlBuL1SAFxXX#pg35

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.