lambda的使用

目录结构:

1:怎么在studio中使用lambda表达式;
2:lambda表达式的使用;

1:怎么在studio中使用lambda表达式

怎么在Android studio项目里面使用java 8的新特性功能lambda表达式呢?
google developer 官方文档里面提供了3种方法:

方法

前提使用JAVA 8
1:使用jack工具链;
jack方式
配置 Gradle
要为您的项目启用 Java 8 语言功能和 Jack,请在模块级别的 build.gradle 文件中输入以下内容:

android {
  ...
  defaultConfig {
    ...
    jackOptions {
      enabled true
    }
  }
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

Instant Run 目前不能用于 Jack,在使用新的工具链时将被停用,所以不建议使用这种方式.
2:使用 Retrolambda插件

配置Gradel
要为您的项目启用 Java 8 语言功能和 retrolambda,请在模块级别的 build.gradle 文件中输入以下内容:

android {
    ...
    defaultConfig {
        ...
    }

    // Keep the following configuration in order to target Java 8.
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
apply plugin: 'me.tatarka.retrolambda'

不明白的细节可以看官方文档

buildscript {
  ...
   dependencies {
      classpath 'me.tatarka:gradle-retrolambda:<version_number>'
   }
}

gradle-retrolambda版本选择
gradle-retrolambda官方文档

3:
前面两种是使用插件完成,第三种,看google文档中写到,Android studio 3.0 preview 1之后,可以不适用工具链插件. 明确指出禁用jack工具链.
前提
To start using supported Java 8 language features, update the Android plugin to 3.0.0-alpha1
(or higher) and add the following to your module’sbuild.gradle
file:
这里的这个plugin 3.0.0-alpha1 不知道怎么搞.等回头试过了更新此部分.

// Keep the following configuration in order to target Java 8.
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

目前推荐使用gradle-retrolambda插件的这种方式.

2:lambda表达式的使用

lambda 表达式有三种形式,分别是:
a:函数式接口
b:方法引用
c:构造器引用

Lambda 表达式由参数列表、箭头和 Lambda 主体(语句块)组成。
( 参数列表... ) -> { 语句块... }

lambda表达式 含义
(String s) -> s.length() 表达式具有一个 String 类型的参数并返回一个 int。 Lambda 没有 return 语句,因为已经隐含的 return,可以显示调用 return。
(T t) -> R 传入参数T,返回一个R类型
(T t) -> void 传入参数T,不返回任何内容
(T1 t,T2 t2,...) -> R 传入多个参数,返回一个R类型
(T1 t,T2 t2,...) -> void 传入多个参数,不返回任何内容

使用lambda表达式的前提是:一个只定义了一个抽象方法的接口,或抽象类.

函数式接口

函数式接口的使用

方法引用

以 Java 的 Predicate 接口作为示例,此接口用来实现判断功能,我们来对字符串进行全面的判空操作:


原始用法

TextUtils 的 isEmpty() 方法实现了上述功能,所以我们可以写作:

方法引用

方法引用形式就是当逻辑实现只有一句且调用了已存在的方法进行处理( this 和 super 的方法也可包括在内)时,对函数式接口形式的 lambda 表达式进行进一步的简化。传入引用方法的参数就是原接口方法的参数。

接下来总结一下方法引用形式的三种格式:

object :: instanceMethod

直接调用任意对象的实例方法,如 obj::equals 代表调用 obj 的 equals 方法与接口方法参数比较是否相等,效果等同 obj.equals(t);。

ClassName :: staticMethod

当前类的方法可用this::method进行调用,父类方法同理。
直接调用某类的静态方法,并将接口方法参数传入,如上述 TextUtils::isEmpty,效果等同 TextUtils.isEmpty(s);

ClassName :: instanceMethod

较为特殊,将接口方法参数列表的第一个参数作为方法调用者,其余参数作为方法参数。由于此类接口较少,故选择 Java 提供的 BiFunction 接口作为示例,该接口方法接收一个 T1 类对象和一个 T2 类对象,通过处理后返回 R 类对象

方法引用2

值得注意的是方法引用图2中的这种方式,固定第一个参数作为方法调用者,其他参数作为方法参数

构造器引用

对于一个现有构造函数,可以利用它的名称和关键字 new 来创建它的一个引用:ClassName::new。它的功能与指向静态方法的引用类似。

例如,假设有一个构造函数没有参数。 它适合 Supplier 的签名() -> Apple。可以这样做:

Supplier<Apple> c1 = Apple::new; //构造函数引用指向默认的 Apple() 构造函数
Apple a1 = c1.get(); //产生一个新的对象

//等价于:

Supplier<Apple> c1 = () -> new Apple(); //利用默认构造函数创建 Apple 的 Lambda 表达式
Apple a1 = c1.get();

Supplier接口

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

如果你的构造函数的签名是Apple(Integer weight),那么它就适合 Function 接口的签名,于是可以这样写:

Function<Integer, Apple> c2 = Apple::new; //构造函数引用指向 Apple(Integer weight) 构造函数
Apple a2 = c2.apple(100);

//等价于:

Function<Integer, Apple> c2 = (Integer weight) -> new Apple(weight);
Apple a2 = c2.apple(100);

类型检查

Lambda 的类型是从使用 Lambda 的上下文推断出来的。上下文(比如接受它传递的方法的参数,或接受它的值的局部变量)中 Lambda 表达式需要的类型称为目标类型。下图表示了代码的类型检查过程:

类型检查

首先,找出 filter 方法的声明;
第二,找出目标类型 Predicate<Apple>。
第三,Predicate<Apple>是一个函数式接口,定义了一个叫作 test 的抽象方法。
第四,test 方法描述了一个函数描述符,它可以接受一个 Apple,并返回一个 boolean。
最后,filter 的任何实际参数都必须匹配这个要求。

搬东搬西凑成了这篇笔记,时不时自己好回忆下.

参考链接

1:lambda 简书

2:郭神公众号

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容