初识Java语言中的lambda表达式和函数式接口

1. lambda表达式

1.1 概述

简单说来,lambda表达式实际上可以理解为一段代码,一段定义了但是却可以按需执行的代码。

1.2 可能好的方面

第一、lambda表达式的功能特性可以帮助java语言做到函数式编程,便于抽象和重构代码。
第二、lambda表达式可以被定义为变量在代码中像传递普通变量一样进行传递,按照实际需要进行一次或者多次执行。
第三、与函数式接口联合使用的时候,使用lambda表达式可以简化代码,代码写起来更加简洁。

1.3 可能要注意

第一、lambda表达式不同于一般的代码形式,一般的代码是写了后,如果代码走到了,里面的代码就会执行,而lambda表达式中的逻辑要被执行的话,还需要额外的一个调用动作。
第二、使用lambda表达式的时候,要注意在lambda表达式中访问不同作用域下的变量的值的安全性,同时异常的处理以及日志记录等要注意。
第三、使用lambda表达式因为简洁,所以有的时候使用过多会带来高度的抽象,可能会导致代码反而不易理解。比如 lambda表达式的参数和返回值的类型都是可以自动推导出来的。当然入参可以加注解让代码清晰点。但是还有各种泛型场景,这样看起来就不是那么明确清晰。

2. 函数式接口

2.1 概述

满足以下2个条件就可以认为是函数式接口:
条件1:是一个接口(interface);
条件2:该接口中抽象方法只有一个。

2.2 可能好的方面

第一、函数式接口的对象,可以通过lambda表达式进行创建,而不用复杂的实现接口的类或者冗长的匿名类。
第二、jdk中自带的函数式接口丰富在java.util.function下很多,使用很方便。
第三、通过lambda表达式和函数式接口的综合使用,便于针对代码具备一定规律行为的抽象,提升代码的层次感。

2.3 可能要注意

第一、如果一个interface中有好几个方法,它有可能是函数式接口,只要它的方法中只有一个未实现的方法即可。例如:

package lambda;

public interface MultiMethodFunctionInterface {
    String getDisplayName();

    public default String getName() {
        return "---";
    }
    public  static void doSth()
    {
        System.out.println("I am doing something.");
    }
}

第二、函数式接口为了明确,我们可以在自定义的函数式接口定义处加上对应的@functionalinterface注解

第三、函数式接口中的抽象方法的参数,尽量控制在3个以内,参数太多的使用起来容易引起理解的复杂性。如果参数就是比较多的话,建议使用类似POJO类的形式把参数进行合理的类定义,以此减少参数的个数。

3. lambda表达式调用形式

3.1 方法引用或构造方法引用

2种形式:
形式1:e -> String.valueOf(e);
形式2: String::valueOf
其中双冒号::的操作符会有几种常见形式:
对象::对象的示例方法
类::类的静态方法
类::new
this::方法
super::方法

3.2 lambda表达式中作用域的问题

lambda表达式是一段代码,这段代码会包括3个部分,
第一,自己独立的代码,
第二,方法的参数,
第三,该lambda表达式所能访问的自由的变量。
关于最后一点,要特别重视,容易在多并发的场景引起问题。因此有个重要的的约束,虽然编译器会有一定的控制,但是注意不能完全检查的出来的,lambda表达式中被引用的自由的变量的值在lambda表达式中是不能被修改的,或者说编码者应该确保被引用的变量可以认为是自动带了final的修饰,然后即使这样还是有些很隐晦的编译器检查不出来,比如List的变量,在lambda表达式中改它里面的元素也是多线程不安全的。
因此,对于lambda表达式在多线程的场景下,为了线程安全,尽量避免在lambda表达式中调用类的成员变量,类的静态变量等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值