30分鐘入門Java8之lambda表達式

前言

Google在今年發佈Android N開發者預覽版,一併宣佈開始支持Java 8。咱們終於能在Android開發中使用到Java8的一些語言特性了。目前支持:html

  • 默認方法
  • lambda表達式
  • 屢次註解

今天咱們就簡要學習lambda表達式。android

配置開發環境

首先須要下載安裝JDK1.8。git

若是想在Android開發中使用lambda表達式,須要在Android Studio中配置Java 8開發環境。github

配置app的Gradle文件:app

  • 開啓jack編譯選項
  • 設置編譯選項兼容到1.8
android {
    defaultConfig {
        ...
        //開啓jack編譯
        jackOptions {
            enabled true
        }
    }
   ...
   //將編譯選項設置爲Java1.8
    compileOptions {
        targetCompatibility 1.8
        sourceCompatibility 1.8
    }
}

出於種種緣由,可能咱們使用的JDK版本是1.7甚至更低,可是咱們又想學習使用lambda表達式,怎麼辦呢?Github上已經有開發者設計了兼容lambda表達式到Java7,6,5的開源庫retrolamda。至於如何在Android Studio中配置,在此就不囉嗦了。能夠參看Gradle Retrolambda Pluginide

第一個lambda表達式

看到下面的代碼,相信你們都會很是熟悉。這不就是給button設置監聽事件嘛。函數

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("TAG","按鈕被點擊,匿名內部類");
            }
        });

分析上面的代碼,這是經過匿名內部類來設置Button的點擊監聽事件的。也就是說,咱們建立了一個實現了View.OnClickListener接口的匿名類的對象。匿名內部類實現了onClick方法。經過這個匿名類的對象,咱們在用戶點擊按鈕時,打印出日誌。學習

但是,你們有沒有發現。上面那段代碼,真正有用的就是Log.d("TAG","按鈕被點擊,匿名內部類");這一行代碼,這就反映了使用匿名內部類的缺點:gradle

  • 可讀性差,不能直接明瞭的體現咱們的意圖。
  • 囉嗦,一行邏輯代碼卻有幾行模板代碼。

而lambda表達式很好的解決了這些問題:設計

button.setOnClickListener(view-> Log.d(TAG,"按鈕被點擊,lambda表達式"));

view-> Log.d(TAG,"按鈕被點擊,lambda表達式"));就是咱們寫的第一個lambda表達式。

由上圖可知,lambda表達式一般以(argument)->(body)這樣的格式書寫。

//省略參數類型
(arg1,arg2...) -> {body}

//指定參數類型
(Type1 arg1,Type2 arg2...)->{body}

lambda表達式中,參數的類型可省略。Java編譯器根據表達式的上下文推導出參數的類型。就像上面圖中view的類型是View

lambda表達式的結構

  • 參數能夠是零個或多個
  • 參數類型可指定,可省略(根據表達式上下文推斷)
  • 參數包含在圓括號中,用逗號分隔
  • 表達式主體能夠是零條或多條語句,包含在花括號中
  • 表達式主體只有一條語句時,花括號可省略
  • 表達式主體有一條以上語句時,表達式的返回類型與代碼塊的返回類型一致
  • 表達式只有一條語句時,表達式的返回類型與該語句的返回類型一致
//零個
 ()-> System.out.println("no argument");
 
//一個
  x->x+1

//兩個
  (x,y)->x+y

//省略參數類型
 View.OnClickListener oneArgument = view->Log.d(TAG,"one argument");
 //指定參數類型
 View.OnClickListener oneArgument = (View view)->Log.d(TAG,"one argument");

//多行語句
//返回類型是代碼塊返回的void
View.OnClickListener multiLine = (View view)->{
      Log.d(TAG,"multi statements");
      Log.d(TAG,"second line");
}

//返回類型是表達式主體語句的返回類型int
(int x)->x+1

lambda表達式的類型

咱們都知道,Java是一種強類型語言。全部的方法參數都有類型,那麼lambda表達式是一種什麼類型呢?

View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //...
            }
        };
        
 button.setOnClickListener(listener);

如上所示,以往咱們是經過使用單一方法的接口來表明一個方法而且重用它。

在lambda表達式中,仍使用的和以前同樣的形式。咱們叫作函數式接口(functional interface)

如咱們以前button的點擊響應事件使用的View.OnClickListener就是一個函數式接口。

public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
        ...
 public interface OnClickListener {
        void onClick(View v);
    }
    ...
    }

那究竟什麼樣的接口是函數式接口呢?

函數式接口是隻有一個抽象方法的接口。用做表示lambda表達式的類型。

Java8 API中新增了許多函數式接口:

接口名 參數 返回值 用途
Predicate T boolean 斷言
Consumer T void 消費
Function<T,R> T R 函數
Supplier None T 工廠方法
UnaryOperator T T 邏輯非
BinaryOperator (T,T) T 二元操做
相關文章
相關標籤/搜索