Jadual Kandungan
前言
Jack 配置
retrolambda 配置
Lambda expression的使用方式
最简单的Lambda expression
有参数且有返回值的Lambda expression
自定义接口,并使用Lambda expression
使用Lambda expression简化命令者模式
示例 (原来的实现)
Lambda expression 简化版
Rumah Java javaTutorial 详细介绍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
    }
}
Salin selepas log masuk

以启用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
    }}
Salin selepas log masuk

注:很多开源的项目,还是使用的retrolambda

Lambda expression的使用方式

首先,我们要知道的是,该表达式,整体上是表达了一个『对象类型』。

最简单的Lambda expression

代码:

Runnable runnable = () -> System.out.println("hi, 我是 stone");runnable.run();
Salin selepas log masuk

()其实就是方法参数列表,这里没有传参数,那么就会去匹配无参的方法,因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);
});
Salin selepas log masuk

有参数时,只要传参数名字即可,名字可随意定义;类型定义或不定义都可以;不定义时,编译器会自动推断。
有返回值时,可以在方法体中,使用return;也可以在只有一段代码时,省略return,如下:

button.setOnTouchListener((v, e) -> super.onTouchEvent(e));
Salin selepas log masuk

自定义接口,并使用Lambda expression

首先定义只有一个抽象方法的接口:

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

定义方法,参数为上面定义的接口:

    void print(IGetData<String> data) {        
    String msg = data.get();        
    System.out.println(msg);
    }
Salin selepas log masuk

使用Lambda expression 作为参数, 调用print():

        print(() -> "张三");        print(() -> {
            System.out.println("干活了");            return "李四";
        });
Salin selepas log masuk

输出:

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: 李四
Salin selepas log masuk

使用Lambda expression简化命令者模式

命令者模式的特征及简单实现流程:

  • 一个命令者 接口, 定义 一个统一执行命令的抽象方法

  • 每个具体命令者都实现 命令者接口,并依赖一个 接收者对象, 命令的执行代理给接收者来执行

  • 调用者类,依赖一个命令者接口对象,由命令者接口来执行。 多态传入不同的具体命令者, 最终由接收者采取不同的执行方式

示例 (原来的实现)

比如,有一些文件操作命令:open, close, save, delete,接收者为一个编辑器editor
那,首先,需要定义一个命令接口:IAction

public interface IAction {//原 命令者  抽象出一个 执行命令的方法
    void perform();
}
Salin selepas log masuk

再定义四个具体命令者类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();
    }
}
Salin selepas log masuk

其他三个实现与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");
      }
}
Salin selepas log masuk

注:如果说不同的编辑器对这些命令都有各自不同的实现,那么也可以定义一个IEditor接口,再实现不同的Editor。关于此点就不详细讨论了

最后还要有一个调用者,可以是一个类:

public class Invoker {  
    private IAction action;  

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

    public void invoke() {  
        this.action.perform();  
    }  
}
Salin selepas log masuk

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();
Salin selepas log masuk

这里的调用者,可以不使用类的方式定义,而是定义成client中的一个方法:

private void invoke(IAction action) {
    action.perform();
}
Salin selepas log masuk

client发起命令调用:

 invoke(new OpenAction(editor)); 
 invoke(new CloseAction(editor)); 
 invoke(new SaveAction(editor)); 
 invoke(new DeleteAction(editor));
Salin selepas log masuk

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());
Salin selepas log masuk

这样,使用Lambda expression后,就省略了具体命令者类的定义。并能一目了然地看到最终执行的是哪个方法。

不用担心这样书写后,会破坏原本命令者模式的 请求与执行分离 的作用。
因 invoke(() -> editor.open()); <==>

invoke(new IAction() {    @Override
    public void perform() {
        editor.open();
    }
});
Salin selepas log masuk

如果保留调用类Invoker,那就类似如下调用:

new Invoker(() -> editor.open()).invoke();
Salin selepas log masuk

Atas ialah kandungan terperinci 详细介绍Android使用Java8新特性之Lambda expression的示例代码. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimanakah ungkapan lambda mengendalikan pengecualian dalam C++? Bagaimanakah ungkapan lambda mengendalikan pengecualian dalam C++? Apr 17, 2024 pm 12:42 PM

Dalam C++, terdapat dua cara untuk mengendalikan pengecualian menggunakan ungkapan Lambda: tangkap pengecualian menggunakan blok cuba-tangkap dan kendalikan atau buang semula pengecualian dalam blok tangkapan. Menggunakan fungsi pembalut jenis std::function, kaedah try_emplacenya boleh menangkap pengecualian dalam ungkapan Lambda.

Bagaimana untuk mengira tarikh setahun yang lalu atau setahun kemudian di Java 8? Bagaimana untuk mengira tarikh setahun yang lalu atau setahun kemudian di Java 8? Apr 26, 2023 am 09:22 AM

Java8 mengira tarikh setahun yang lalu atau setahun kemudian menggunakan kaedah tolak() untuk mengira tarikh setahun yang lalu packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[ ]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

Apakah maksud penutupan dalam ungkapan lambda C++? Apakah maksud penutupan dalam ungkapan lambda C++? Apr 17, 2024 pm 06:15 PM

Dalam C++, penutupan ialah ungkapan lambda yang boleh mengakses pembolehubah luaran. Untuk membuat penutupan, tangkap pembolehubah luar dalam ungkapan lambda. Penutupan memberikan kelebihan seperti kebolehgunaan semula, penyembunyian maklumat dan penilaian malas. Ia berguna dalam situasi dunia sebenar seperti pengendali acara, di mana penutupan masih boleh mengakses pembolehubah luar walaupun ia dimusnahkan.

Apakah kelebihan menggunakan ungkapan lambda C++ untuk pengaturcaraan berbilang benang? Apakah kelebihan menggunakan ungkapan lambda C++ untuk pengaturcaraan berbilang benang? Apr 17, 2024 pm 05:24 PM

Kelebihan ungkapan lambda dalam pengaturcaraan berbilang benang C++ termasuk kesederhanaan, fleksibiliti, kemudahan lulus parameter dan selari. Kes praktikal: Gunakan ungkapan lambda untuk mencipta berbilang benang dan mencetak ID benang dalam urutan yang berbeza, menunjukkan kesederhanaan dan kemudahan penggunaan kaedah ini.

Bagaimana untuk melaksanakan penutupan dalam ungkapan C++ Lambda? Bagaimana untuk melaksanakan penutupan dalam ungkapan C++ Lambda? Jun 01, 2024 pm 05:50 PM

Ungkapan C++ Lambda menyokong penutupan, yang menyimpan pembolehubah skop fungsi dan menjadikannya boleh diakses oleh fungsi. Sintaks ialah [capture-list](parameters)->return-type{function-body}. capture-list mentakrifkan pembolehubah untuk ditangkap Anda boleh menggunakan [=] untuk menangkap semua pembolehubah tempatan mengikut nilai, [&] untuk menangkap semua pembolehubah tempatan melalui rujukan, atau [variable1, variable2,...] untuk menangkap pembolehubah tertentu. Ungkapan Lambda hanya boleh mengakses pembolehubah yang ditangkap tetapi tidak boleh mengubah suai nilai asal.

Bagaimanakah ungkapan lambda C++ menangkap pembolehubah luaran? Bagaimanakah ungkapan lambda C++ menangkap pembolehubah luaran? Apr 17, 2024 pm 04:39 PM

Terdapat tiga cara untuk menangkap ungkapan lambda pembolehubah luaran dalam C++: Tangkap mengikut nilai: Buat salinan pembolehubah. Tangkap melalui rujukan: Dapatkan rujukan berubah-ubah. Tangkap mengikut nilai dan rujukan serentak: Membenarkan tangkapan berbilang pembolehubah, sama ada mengikut nilai atau rujukan.

Bagaimana untuk mengira tarikh seminggu kemudian menggunakan Java 8? Bagaimana untuk mengira tarikh seminggu kemudian menggunakan Java 8? Apr 21, 2023 pm 11:01 PM

Cara mengira tarikh seminggu kemudian dalam Java8 Contoh ini akan mengira tarikh seminggu kemudian. Tarikh LocalDate tidak mengandungi maklumat masa kaedah tambah() digunakan untuk menambah hari, minggu dan bulan Kelas ChronoUnit mengisytiharkan unit masa ini. Memandangkan LocalDate juga merupakan jenis yang tidak boleh diubah, anda mesti menggunakan pembolehubah untuk menetapkan nilai selepas kembali. packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

Panggilan fungsi C++ Ekspresi Lambda: pengoptimuman panggil balik untuk menghantar parameter dan nilai pulangan Panggilan fungsi C++ Ekspresi Lambda: pengoptimuman panggil balik untuk menghantar parameter dan nilai pulangan May 03, 2024 pm 12:12 PM

Dalam C++, anda boleh menggunakan ungkapan Lambda sebagai parameter fungsi untuk mencapai fleksibiliti fungsi panggil balik. Khususnya: Hantaran parameter: balut ungkapan Lambda melalui fungsi std:: dan hantarkannya kepada fungsi dalam bentuk penuding fungsi. Pemprosesan nilai pulangan: Tentukan jenis nilai pulangan apabila mengisytiharkan penunjuk fungsi panggil balik menggunakan fungsi std::. Kes praktikal: Optimumkan panggilan balik dalam pemprosesan acara GUI, elakkan daripada mencipta objek atau penunjuk fungsi yang tidak diperlukan dan meningkatkan kesederhanaan dan kebolehselenggaraan kod.

See all articles