一文学会使用Lambda表达式

Java8的函数式编程

Posted by songjunhao on February 21, 2019

lambda 表达式简介

类是对象的抽象,接口是行为的抽象。

lambda 表达式 是 Java8 的新特性。lambda表达式用于简化方法的参数传递。使用lambda表达式,可以简化代码,提高代码可读性,便于维护。

在JDK1.8之前,只有对象可以作为参数进行传递,不可以直接将代码作为参数进行传递。而在Java8中,使用Lambda表达式便可以将代码作为参数进行传递。

使用Lambda表达式进行编程的代码又称函数式风格代码。

lambda 表达式示例与对比

接口是行为的抽象,代码是具体的行为。

在方法的参数中传递 【代码】= 传递 【具体的行为】 = 传递 【接口】 。

在Java8之前,我们想要在参数中 传递 接口,有两种方式,一种是传递接口实现类,一种是传递匿名内部类,两种方式的代码都会有很多额外的”模板”代码。

Java8之前:接口使用匿名内部类方式作为参数:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("我是匿名内部类方试的执行,代码是真的多呀");
    }
}).start();

Java8:接口使用 lambda 表达式作为参数:

new Thread(() -> System.out.println("执行操作")).start();

对比匿名内部类及lambda表达式,我们可以发现,省去了很多与业务无关的代码,可读性提高了很多。

上述代码中lambda表达式,实际上是替换了Runnable接口的匿名内部类的那一部分代码,在Java8中,大部分的接口匿名内部类都可以使用 lambda 表达式进行简化替换。

那么什么样的接口才可以使用 lambda 表达式进行简化呢,请往下看。

函数接口 @FunctionalInterface

lambda 表达式用于 简化 方法的 参数 为 接口 的代码。

但可以被lambda表达式简化的接口,是有条件的,那就是接口必须为 函数接口

函数接口是指 接口中除了 default 方法外,只有一个方法声明。 例如:

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

其中 @FunctionalInterface 注解是Java8新提供的注解,与@Override类似,用于编译检查,使用此注解可以帮你检查接口是否符合 函数接口的规范。

lambda表达式使用说明

lambda表达式 是作用于 方法参数为 函数接口 的一种语法,用于减少 传递接口参数时的非业务代码。所有的 方法参数 是 函数接口 的方法,在调用该方法时,都可以使用 lambda 表达式。

基本使用方式 1

lambda 表达式拥有多种写法,首先介绍第一种,如下图所示,下图展示了匿名内部类方式如何转换为 lambda表达式 方式。其中lambda表达式中的 (s) s 表示 入参,入参名可任意定义。箭头表示 参数 指向 行为

如果是多个入参,可以 逗号 分割,如下图所示:

在使用匿名内部类作为方法调用的参数传递时,同样也可以将其替换为 lambda表达式,如下图所示:

基本使用方式 2

使用方式 1 中的 lambda 表达式 可以进行简化,下面说明如何进行简化。

1.lambda表达式的 参数 可以不声明类型,如下图所示。

2.如果 lambda 表达式的 参数 只有一个,那么可以不写扩号,没有参数或者有多个参数必须写扩号,如下图所示。

3.如果 具体行为的代码 为 直接结果表达式(非return的单行执行语句),则可以不写 两边的 大括号,如下图所示。

如果你看懂了上面的内容,那么恭喜你,你已经完全学会使用 lambda 表达式啦。下面将介绍针对 lambda 表达式的 简化语法 – 方法引用

方法引用 “::”

方法引用 是 Java8 新增的语法,可以 对 满足条件的 lambda 表达式 再进行简化。

方法引用 的 具体使用方式:如果 具体行为的 代码 为 直接结果表达式,且 具体行为的代码 的 参数 为 lambda 表达式的参数,则可以直接通过 类名::方法名 或者 对象名::方法名 的方式直接调用。

1.静态方法可以使用 类名::方法名 的方式使用 方法引用,如下图所示:

2.对象和静态方法一样,也可以使用 方法引用 ,对象名::方法名,如下图所示:

总结

看到这里相信你已经学会了 函数式编程 lambda 表达式的使用~ 现在开始,调用方法时,可以考虑一下,参数是否为 函数接口,如果是的话,可以考虑使用 lambda 表达式进行参数传递。

欢迎评论分享见解~