JavaLambda详解
Lambda表达式是JDK 8开始后的一种新语法形式。
作用:简化匿名内部类的代码写法 简化格式(匿名内部类被重写方法的形参列表) -> { 重写方法 }
Lambda表达式只能简化函数式接口的匿名内部类的写法形式 什么是函数式接口?首先必须是接口、其次接口中有且仅有一个抽象方法的形式 通常会在接口上加上一个@FunctionalInterface注解,标记该接口必须是满足函数式接口 如何使用Lambda?
我们将根据下面三个问题来帮助大家理解和使用Lambda
背景:我们自定义了一个man的类,创建了一个man的List。 class man { public int age; public char sex; public double socre; public man(int age, char sex, double score) { this.age = age; this.sex = sex; this.score = score; } }问题一现需要对这个list根据人的年龄进行排序
要实现排序的功能,可以直接调用List对象自带的sort方法完成,但是需要man先实现Comparator的接口并重写compare方法,编译器才能比较两个不同man的大小。但是要更改原始类的代码,会比较麻烦,如果以后要对人的分数进行排序,那就又要更改原始类的源码,这样操作很不方便。
sort(Comparator<? super E> c) 方法可以直接传入一个Comparator对象,我们可以直接改写compare方法就可以实现比较。 第一种写法public class lambdaTry { public static void main(String[] args) { List humans = new ArrayList<>(); humans.add(new man(19, "g", 98.0)); humans.add(new man(18, "b", 95.0)); humans.add(new man(20, "b", 96.0)); humans.add(new man(17, "g", 97.0)); humans.sort(new Comparator() { @Override public int compare(man o1, man o2) { return o1.age - o2.age; } }); } }第二种写法
Lambda
我们知道Lambda是用来简化函数式接口的匿名内部类,且Comparator满足函数式接口的两个条件: 首先必须是接口、其次接口中有且仅有一个抽象方法的形式 @FunctionalInterface注解 @FunctionalInterface public interface Comparator { int compare(T o1, T o2); ... }
因此我们可以对上述的源码进行改写成Lambda格式 public class lambdaTry { public static void main(String[] args) { List humans = new ArrayList<>(); humans.add(new man(19, "g", 98.0)); humans.add(new man(18, "b", 95.0)); humans.add(new man(20, "b", 96.0)); humans.add(new man(17, "g", 97.0)); humans.sort((man o1, man o2) -> { return o1.age - o2.age; }); } }
改写过后代码简洁了很多。但是还可以继续简写。 Lambda表达式的省略写法参数类型可以不写 如果只有一个参数,参数类型可以省略,同时()也可以省略 如果Lambda表达式的方法块中代码只有一行,可以省略大括号,同时省略分号。 在条件三的基础上,如果这行代码是return语句,必须省略return。 第三种写法
Lambda简写
可以看到,此表达式满足省略写法的条件,可以继续简写成如下格式。只需要一行语句就能完成 public class lambdaTry { public static void main(String[] args) { List humans = new ArrayList<>(); humans.add(new man(19, "g", 98.0)); humans.add(new man(18, "b", 95.0)); humans.add(new man(20, "b", 96.0)); humans.add(new man(17, "g", 97.0)); humans.sort((o1, o2) -> o1.age - o2.age); } }问题二将List转换为数组
我们知道List接口有一个方法toArray方法可以实现将其转换为数组。
JDK11之后,提供了这样的一个方法,提供了一个函数式接口来让我们转换 default T[] toArray(IntFunction generator) { return toArray(generator.apply(0)); }
IntFunction函数式接口是从JDK8之后实现的,内部只有一个apply抽象方法,是一个标准的函数式接口 @FunctionalInterface public interface IntFunction { R apply(int value); }
我们可以直接用lambda,完成数组的转换 public class lambdaTry { public static void main(String[] args) { List humans = new ArrayList<>(); humans.add(new man(19, "g", 98.0)); humans.add(new man(18, "b", 95.0)); humans.add(new man(20, "b", 96.0)); humans.add(new man(17, "g", 97.0)); // 原本写法 // man[] mans = humans.toArray(new IntFunction() { // @Override // public man[] apply(int value) { // return new man[value]; // } // }); // lambda写法 man[] mans = humans.toArray(value -> new man[value]); // 实际上用不上这样的写法,只是为了举例说明 // man[] mans = humans.toArray(new man[0]); // man[] mans = humans.toArray(man[]::new); // 上面两种写法都可以,传值进去的size为0不影响实际的转换,具体可以看ArrayList的toArray重写方法 } }问题三输出年龄大于18的男同学的成绩
可以用forEach方法快捷实现,forEach方法来自于Iterable接口 default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
再看Consumer接口,也是一个函数式接口 @FunctionalInterface public interface Consumer { void accept(T t); ... }
具体实现 public class lambdaTry { public static void main(String[] args) { List humans = new ArrayList<>(); humans.add(new man(19, "g", 98.0)); humans.add(new man(18, "b", 95.0)); humans.add(new man(20, "b", 96.0)); humans.add(new man(17, "g", 97.0)); // humans.forEach(new Consumer<>() { // @Override // public void accept(man man) { // if (man.age >= 18 && man.sex == "g") { // System.out.println(man.score); // } // } // }); humans.forEach(man -> { if (man.age >= 18 && man.sex == "g") { System.out.println(man.score); } }); } }
有时Lambda还可以继续简写成方法引用(method reference) 方法引用
方法引用通过方法的名字来指向一个方法。
方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
方法引用使用一对冒号 ::
主要分为四种: 构造器引用 Class::new man[] mans = humans.toArray(man[] ::new ); 静态方法引用 Class::static_method 打印每个man(需要在man内重写toString)humans .forEach ( System .out ::println) 特定类的任意对象的方法引用 Class::method 特定对象的方法引用 instance::method
如果你觉得这篇文章对你有帮助 点赞关注,然后私信回复【888】即可免费获取Java进阶全套视频以及源码学习资料
极米H3S旗舰大升级从口碑爆款到销额过亿,极米到底做了什么?一提到极米的投影,很多人都知道H3响当当的名号,可以说在一段时间里极米H3代表了极米从硬件到软件研发旗舰级的水准。不仅是赢得了科技发烧友的喜爱,更是获得了万千家庭的认可,而根据国际
空间大配置高奔腾T99到底值不值?近几年来,国产车一直在不断进步着,现在随着中国的技术不断进步,我们也可以开上我们国产的好车,一汽奔腾就有很大的提升,从换标志再到推出奔腾T99,并没有让我们等太长时间,那么这款售价
真的很庆幸当初选择了它,我的摩卡年轻时尚高颜值还有运动气息,它就是我的摩卡,我看到它的第一眼就被它的颜值所吸引。虽然它是一辆国产车,在各个方面都比同等级同价位的车优秀,包括合资车。摩卡的高智能和时尚得体的高颜值外
15场专为中国Prime会员定制惊喜优惠轮番登场2020年9月28日,北京亚马逊今日宣布,亚马逊Prime会员日将于10月13日全球同步开启,为19个国家的Prime会员奉上逾百万专享超值优惠。本届Prime会员日期间,中国消费
沃尔沃方锡智就东莞三惠沃尔沃开业发表讲话很高兴能和大家欢聚在这里,共同庆祝东莞三惠沃尔沃授权经销商开业!在此,我谨代表沃尔沃汽车向在座的各位贵宾致以诚挚的问候,并向三惠汽车集团表示热烈的祝贺!对汽车行业有所了解的人都知道
亚马逊海外购选品突破三千万重磅开启史上最长海外购物节2020年9月21日,北京亚马逊中国宣布正式开启长达三个月的海外购物节,为消费者打造亚马逊中国海外购史上最长的巅峰钜惠活动。亚马逊中国第七届海外购物节横跨整个第四季度,将涵盖202
说说这款增程式车型的代表岚图FREE!讨论増程车型是否可以购买,我们要讨论的实际上是三个问题首先,为什么不一定是纯电?其次,增程技术到底如何?第三,这款车如何?第一个问题,为什么不一定是纯电?纯电车型是对充电基础设施依
比亚迪的车凭什么卖得比大众贵?作为自主品牌的代表,比亚迪的单车均价已经超越了最热门的合资品牌大众汽车。汽车产业数字化应用服务商威尔森监测的数据显示,2021年17月份,比亚迪的单车均价已经达到15。18万元,不
重磅!轩辕之学铃轩2期正式招生一叶知秋。2021年刚刚立秋,轩辕之学铃轩2期正式启动招生工作,招募那些能够一起奔向未来的汽车零部件企业精英。这必将是一群不怕新汽车时代给自己算账的时代先锋。当下的全球汽车产业正处
基因港两次突破让中国NMN产业走向世界基因港,全称基因港(香港)生物科技有限公司,这家由香港中文大学教授王骏所创办的企业,几乎凭借一己之力将中国NMN产业推向了世界之巅。然而,在基因港成功光环的背后,却隐藏着众多鲜为人
比亚迪汉唐精英荟成员汉唐车主为中国队夺得1金2银1铜东京2020年奥运会落下帷幕,中国代表团表现优异,以38枚金牌32枚银牌18枚铜牌圆满收官。中国皮划艇队和赛艇队更是迎来高光时刻,以2金2银2铜创历史最佳成绩!百舸争流,气吞万里如