目錄
前言
Jack 設定
retrolambda 設定
Lambda expression的使用方式
最簡單的Lambda expression
有參數且有回傳值的Lambda expression
自訂接口,並使用Lambda expression
使用Lambda expression簡化命令者模式
#範例(原來的實作)
Lambda expression 簡化版
首頁 Java java教程 詳細介紹Android使用Java8新功能之Lambda expression的範例程式碼

詳細介紹Android使用Java8新功能之Lambda expression的範例程式碼

Mar 11, 2017 am 11:54 AM

前言

Lambda expression,java8的新特性。使用Lambda expression,可以取代只有一個函數的介面實現,告別匿名內部類,程式碼看起來更簡潔易懂。
java8還有其它一些新特性,不過在android上可能都無法使用。
studio 2.x後 支援jack編譯器,使用它,能使用java8的Lambda expression,但其它特性也不敢保證就能用。

註:Android SDK中整合了JDK的一些原始碼,有些原生JDK中的類,可能增加了新特性的一些實現,但Android中的並沒有。再例如java8的java.util.function包,在低版本中也是沒有的

也可以使用插件retrolambda來支援java8的Lambda expression。

Jack 設定

新增以下設定

android {
    jackOptions {
        enabled true
    }
    compileOptions {//jack、retrolambda编译必需        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
登入後複製

以啟用jack編譯器,來支援Lambda expression

使用最新2.3版studio,jdk 1.8 的環境, gradle2.3,和如上的配置
 經測試,在4.4的模擬器上也是可以跑的
 配置Demo :http://www.php.cn/

retrolambda 設定

retrolambda 相容於java5、6、7使用Lambda expression。

配置如下

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'me.tatarka:gradle-retrolambda:3.6.0'
    }}
apply plugin: 'me.tatarka.retrolambda'android {
    defaultConfig {
        minSdkVersion 11 //这个没有硬性要求
    }
    compileOptions {//jack、retrolambda编译必需
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }}
登入後複製

註:很多開源的項目,還是使用的retrolambda

Lambda expression的使用方式

首先,我們要知道的是,該表達式,整體上是表達了一個『物件類型』。

最簡單的Lambda expression

程式碼:

Runnable runnable = () -> System.out.println("hi, 我是 stone");runnable.run();
登入後複製

()其實就是方法參數列表,這裡沒有傳參數,那麼就會去匹配無參的方法,因Runnable只有一個void run(),所以會配對到它;這裡沒有寫方法名,所以方法的名字會被忽略。

-> 這個後面跟著方法體。這裡只有一句列印程式碼,可以省略方法體的花括號:{} 。

註:這裡也省略了」new Runnable」這樣的程式碼,是因為編譯器會進行自動的型別推斷。如果直接呼叫() -> System.out.println(“hi, 我是stone”).run(); 那麼是編譯不過的,因為編譯器不知道要去哪個類別找對應的方法

有參數且有回傳值的Lambda expression

程式碼:

button.setOnTouchListener((view, event)-> {    
if (event.getAction() == MotionEvent.ACTION_DOWN) {        
if (flag) {            
return true;
        }
    }    return super.onTouchEvent(event);
});
登入後複製

有參數時,只要傳參數名字即可,名字可隨意定義;型別定義或不定義都可以;不定義時,編譯器會自動推斷。
有回傳值時,可以在方法體中,使用return;也可以在只有一段程式碼時,省略return,如下:

button.setOnTouchListener((v, e) -> super.onTouchEvent(e));
登入後複製

自訂接口,並使用Lambda expression

#首先定義只有一個抽象方法的介面:

    interface IGetData<T> {//lambda只能用于单一方法类型匹配
        T get();//      T getOne(int i); //多个抽象方法,直接编译不过
    }
登入後複製

定義方法,參數為上面定義的介面:

    void print(IGetData<String> data) {        
    String msg = data.get();        
    System.out.println(msg);
    }
登入後複製

使用Lambda expression 作為參數,呼叫print():

        print(() -> "张三");        print(() -> {
            System.out.println("干活了");            return "李四";
        });
登入後複製

輸出:

03-08 06:46:00.430 1510-1510/? I/System.out: 张三
03-08 06:46:00.430 1510-1510/? I/System.out: 干活了
03-08 06:46:00.430 1510-1510/? I/System.out: 李四
登入後複製

使用Lambda expression簡化命令者模式

命令者模式的特徵及簡單實現流程:

  • 一個命令者接口, 定義一個統一執行命令的抽象方法

  • 每個特定命令者都實現命令者接口,並依賴一個接收者對象,  命令的執行代理給接收者來執行

  • 呼叫者類,依賴一個命令者介面對象,由命令者介面來執行。 多態傳入不同的具體指令者, 最終由接收者採取不同的執行方式

#範例(原來的實作)

例如,有一些檔案操作指令:open, close, save, delete,接收者為一個編輯器editor
那,首先,需要定義一個指令介面:IAction

public interface IAction {//原 命令者  抽象出一个 执行命令的方法
    void perform();
}
登入後複製

再定義四個特定指令者類別OpenAction、CloseAction、SaveAction、DeleteAction。
CloseAction程式碼:

public class CloseAction implements IAction {
    private Editor mEditor;    
    public CloseAction(Editor editor) {        
    this.mEditor = editor;
    }    
    @Override
    public void perform() {        
    this.mEditor.close();
    }
}
登入後複製

其他三個實作與CloseAction類似。

Editor類別(接收者),就定義了收到四個命令的各個具體實現:

public class Editor {     public void save() {
          System.out.println("save");
      }      public void delete() {
          System.out.println("delete");
      }      public void open() {
          System.out.println("open");
      }      public void close() {
          System.out.println("close");
      }
}
登入後複製

註:如果說不同的編輯器對這些命令都有各自不同的實現,那麼也可以定義一個IEditor接口,再實現不同的Editor。關於此點就不詳細討論了

最後還要有一個呼叫者,可以是一個類別:

public class Invoker {  
    private IAction action;  

    public Invoker(IAction action) {  
        this.action = action;  
    }  

    public void invoke() {  
        this.action.perform();  
    }  
}
登入後複製

client發起指令:

Editor editor = new Editor();
new Invoker(new OpenAction(editor)).invoke();
new Invoker(new CloseAction(editor)).invoke();
new Invoker(new SaveAction(editor)).invoke();
new Invoker(new DeleteAction(editor)).invoke();
登入後複製

這裡的呼叫者,可以不使用類別的方式定義,而是定義成client中的一個方法:

private void invoke(IAction action) {
    action.perform();
}
登入後複製

client發起指令呼叫:

 invoke(new OpenAction(editor)); 
 invoke(new CloseAction(editor)); 
 invoke(new SaveAction(editor)); 
 invoke(new DeleteAction(editor));
登入後複製

Lambda expression 簡化版

保留IAction、Editor和client中的invoke(Iaction action)。

client發起指令呼叫:

  Editor editor = new Editor();
  invoke(() -> editor.open());  
  invoke(() -> editor.close());  
  invoke(() -> editor.save());  
  invoke(() -> editor.delete());
登入後複製

這樣,使用Lambda expression後,就省略了具體指令者類別的定義。並能一目了然地看到最終執行的是哪個方法。

不用擔心這樣書寫後,會破壞原本指令者模式的 請求與執行分離 的作用。
因 invoke(() -> editor.open());   <==>

invoke(new IAction() {    @Override
    public void perform() {
        editor.open();
    }
});
登入後複製

如果保留呼叫類別Invoker,那就類似如下呼叫:

new Invoker(() -> editor.open()).invoke();
登入後複製

以上是詳細介紹Android使用Java8新功能之Lambda expression的範例程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

lambda 表達式在 C++ 中如何處理異常? lambda 表達式在 C++ 中如何處理異常? Apr 17, 2024 pm 12:42 PM

在C++中,使用Lambda表達式處理異常有兩種方法:使用try-catch區塊捕獲異常,並在catch區塊中處理或重新拋出異常。使用std::function類型的包裝函數,其try_emplace方法可以捕獲Lambda表達式中的異常。

Java 8中如何計算一年前或一年後的日期? Java 8中如何計算一年前或一年後的日期? Apr 26, 2023 am 09:22 AM

Java8計算一年前或一年後的日期利用minus()方法計算一年前的日期packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

C++ lambda 表達式中閉包的意思是什麼? C++ lambda 表達式中閉包的意思是什麼? Apr 17, 2024 pm 06:15 PM

在C++中,閉包是能夠存取外部變數的lambda表達式。若要建立閉包,請擷取lambda表達式中的外部變數。閉包提供可重複使用性、資訊隱藏和延遲求值等優點。它們在事件處理程序等實際情況中很有用,其中即使外部變數被銷毀,閉包仍然可以存取它們。

用 C++ lambda 表達式實作多執行緒程式設計的優點是什麼? 用 C++ lambda 表達式實作多執行緒程式設計的優點是什麼? Apr 17, 2024 pm 05:24 PM

lambda表達式在C++多執行緒程式設計中的優點包括:簡潔性、靈活性、易於傳參和並行性。實戰案例:使用lambda表達式建立多執行緒,在不同執行緒中列印執行緒ID,展示了該方法的簡潔和易用性。

C++ Lambda 表達式如何實作閉包? C++ Lambda 表達式如何實作閉包? Jun 01, 2024 pm 05:50 PM

C++Lambda表達式支援閉包,即保存函數作用域變數並供函數存取。語法為[capture-list](parameters)->return-type{function-body}。 capture-list定義要捕獲的變量,可以使用[=]按值捕獲所有局部變量,[&]按引用捕獲所有局部變量,或[variable1,variable2,...]捕獲特定變量。 Lambda表達式只能存取捕獲的變量,但無法修改原始值。

C++ lambda 表達式如何捕捉外部變數? C++ lambda 表達式如何捕捉外部變數? Apr 17, 2024 pm 04:39 PM

在C++中捕捉外部變數的lambda表達式有三種方法:按值擷取:建立一個變數副本。按引用擷取:獲得變數引用。同時按值和引用捕獲:允許捕獲多個變量,按值或按引用。

如何使用Java 8計算一週後的日期? 如何使用Java 8計算一週後的日期? Apr 21, 2023 pm 11:01 PM

Java8如何計算一週後的日期這個例子會計算一週後的日期。 LocalDate日期不包含時間訊息,它的plus()方法用來增加天、週、月,ChronoUnit類別宣告了這些時間單位。由於LocalDate也是不變型,回傳後一定要用變數賦值。 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

C++ 函式呼叫 Lambda 表達式:參數傳遞與傳回值的回呼最佳化 C++ 函式呼叫 Lambda 表達式:參數傳遞與傳回值的回呼最佳化 May 03, 2024 pm 12:12 PM

在C++中,可以使用Lambda表達式作為函數參數,實現回呼函數的靈活性。具體而言:參數傳遞:透過std::function包裝Lambda表達式,以函數指標形式傳遞給函數。傳回值處理:使用std::function宣告回呼函數指標時指定傳回值類型。實戰案例:優化GUI事件處理中的回調,避免創建不必要的物件或函數指針,提高程式碼簡潔性和可維護性。

See all articles