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接口来实现函数拼接。

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

推荐阅读更多精彩内容