目录
前言
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 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++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表达式中的异常。

C++ lambda 表达式中闭包的含义是什么? C++ lambda 表达式中闭包的含义是什么? Apr 17, 2024 pm 06:15 PM

在C++中,闭包是能够访问外部变量的lambda表达式。要创建闭包,请捕获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 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