lambda表达式

 1、组成

组成Lambda表达式的三要素:形式参数,箭头,代码块。

Lambda表达式的格式。

格式:(形式参数) -> {代码块}。

形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可。

->:由英文中画线和大于符号组成,固定写法。代表指向动作。

代码块:是我们具体要做的事情,也就是以前我们写的方法体内容。

2、使用

Lambda表达式的使用前提:1、有一个接口。2、接口中有且仅有一个抽象方法。

练习一:不带参数

定义一个接口(Eatable),里面定义一个抽象方法:void eat();

定义一个测试类(EatableDemo),在测试类中提供两个方法

一个方法是:useEatable(Eatable e)

一个方法是主方法,在主方法中调用useEatable方法

练习二:带参数、无返回值

定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);

定义一个测试类(FlyableDemo),在测试类中提供两个方法

一个方法是:useFlyable(Flyable f)

一个方法是主方法,在主方法中调用useFlyable方法

练习三:带参数、有返回值

定义一个接口(Addable),里面定义一个抽象方法:intadd(intx,inty);

定义一个测试类(AddableDemo),在测试类中提供两个方法

一个方法是:useAddable(Addable a)

一个方法是主方法,在主方法中调用useAddable方法

3、省略

省略规则:

参数类型可以省略。但是有多个参数的情况下,不能只省略一个

如果参数有且仅有一个,那么小括号可以省略

如果代码块的语句只有一条,可以省略大括号和分号,甚至是return


4、注意事项

使用Lambda必须要有接口,并且要求接口中有且仅有一个抽象方法。

必须有上下文环境,才能推导出Lambda对应的接口。

根据局部变量的赋值得知Lambda对应的接口:Runnable r = () -> System.out.println("Lambda表达式");

根据调用方法的参数得知Lambda对应的接口:new Thread(() -> System.out.println("Lambda表达式")).start();

5、Lambda表达式和匿名内部类的区别

所需类型不同

a.匿名内部类:可以是接口,也可以是抽象类,还可以是具体类

b.Lambda表达式:只能是接口

使用限制不同

a.如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类

b.如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式

实现原理不同

a.匿名内部类:编译之后,产生一个单独的.class字节码文件

b.Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

6、方法引用

解析:

方法引用符:

:: 该符号为引用运算符,而它所在的表达式被称为方法引用。

推导与省略:

a.如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导。

b.如果使用方法引用,也是同样可以根据上下文进行推导。

c.方法引用是Lambda的孪生兄弟。

7、Lambda表达式支持的方法引用

常见的引用方式:引用类方法、引用对象的实例方法、引用类的实例方法、、引用构造器。

1)引用类方法(引用类方法,其实就是引用类的静态方法)

格式:类名::静态方法

范例:Integer::parseInt

             Integer类的方法:public static int  parseInt​(String  s) 将此String转换为int类型数据

2)引用对象的实例方法

引用对象的实例方法,其实就引用类中的成员方法

格式:对象::成员方法

范例:"HelloWorld"::toUpperCase

         String类中的方法:public String toUpperCase​() 将此String所有字符转换为大写


3)引用类的实例方法

引用类的实例方法,其实就是引用类中的成员方法

格式:类名::成员方法

范例:String::substring

         String类中的方法:public String substring​(int beginIndex,int endIndex)     从beginIndex开始到endIndex结束,截取字符串。返回一个子串,子串的长度为endIndex-beginIndex


4)引用构造器

引用构造器,其实就是引用构造方法

格式:类名::new

范例:Student::new

8、函数式接口

函数式接口:有且仅有一个抽象方法的接口。

Java中的函数式编程体现就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口。

只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。

如何检测一个接口是不是函数式接口呢?

@FunctionalInterface

放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败。

注意:

我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算我不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。但是,建议加上该注解。

9、函数式接口作为方法的参数

如果方法的参数是一个函数式接口,我们可以使用Lambda表达式作为参数传递

10、函数式接口作为方法的返回值

如果方法的返回值是一个函数式接口,我们可以使用Lambda表达式作为结果返回

11、常用的函数式接口

java.util.function

功能接口为lambda表达式和方法引用提供目标类型。每个功能接口都有一个抽象方法,称为该功能接口的功能方法,lambda表达式的参数和返回类型与之匹配或匹配。

Supplier接口、Consumer接口、Predicate接口、Function接口。

Supplier接口  

 Supplier<T>:包含一个无参的方法

T get​():获得结果。该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据。

Supplier<T>接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用。


Consumer接口

Consumer<T>:包含两个方法

void accept​(T t):对给定的参数执行此操作。

default Consumer<T> andThen​(Consumer  after):返回一个组合的 Consumer,依次执行此操作,然后执行after操作。

Consumer<T>接口也被称为消费型接口,它消费的数据的数据类型由泛型指定。

练习:

String[]strArray= {"林青霞,30","张曼玉,35","王祖贤,33"};

字符串数组中有多条信息,请按照格式:“姓名:XX,年龄:XX"的格式将信息打印出来

要求:

把打印姓名的动作作为第一个Consumer接口的Lambda实例

把打印年龄的动作作为第二个Consumer接口的Lambda实例

将两个Consumer接口按照顺序组合到一起使用

Predicate接口

Predicate<T>:常用的四个方法

booleantest​(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值。

default Predicate<T> negate​():返回一个逻辑的否定,对应逻辑非。

default Predicate<T> and​(Predicate other):返回一个组合判断,对应短路与。

default Predicate<T> or​(Predicate other):返回一个组合判断,对应短路或。

Predicate<T>接口通常用于判断参数是否满足指定的条件。

练习:

String[]strArray= {"林青霞,30","柳岩,34","张曼玉,35","貂蝉,31","王祖贤,33"};

字符串数组中有多条信息,请通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中,并遍历ArrayList集合

同时满足如下要求:姓名长度大于2;年龄大于33

分析

有两个判断条件,所以需要使用两个Predicate接口,对条件进行判断

必须同时满足两个条件,所以可以使用and方法连接两个判断条件

Function接口

Function<T,R>:(T- 函数输入的类型R- 函数结果的类型)

常用的两个方法: a.   apply​(T t):将此函数应用于给定的参数     b.   default <V> Function andThen​(Function  after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果。

Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值.


练习

String s = "林青霞,30";

请按照我指定的要求进行操作:

1:将字符串截取得到数字年龄部分  

2:将上一步的年龄字符串转换成为int类型的数据

3:将上一步的int数据加70,得到一个int结果,在控制台输出

请通过Function接口来实现函数拼接。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容