詳細介紹Android使用Java8新功能之Lambda expression的範例程式碼
前言
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中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

熱門話題

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

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

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

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

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

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

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