lambada表达式总结
前言
作为jdk1.8的新特性,8的标准库都开始大量使用lambda表达式了,你有什么理由不去学习lambda,这么简洁,这么爽的一种编程方法,不学不觉得可惜吗?
lambda即λ,是匿名函数的意思,在java中,lambda表达式本质上是定义一个匿名内部类而已。即定一个一匿名函数的同时,定义一个匿名内部类。
1、匿名内部类->匿名函数
匿名内部类,可以对接口和抽象类进行使用,直接生成其子类或实现类对象。
现有一个接口,其内有一个抽象方法。
public interface Ability {void doAbility(String token);
}
当我们想用匿名内部类的时候,即可以不通过定义子类或实现类,直接获得子类对象或实现类对象,如下:
public class LOLHero {public static void main(String[] args) {Ability ability = new Ability(){@Overridepublic void doAbility(String token) {System.out.println("我只是一个栗子");}};}
}
哈哈,下面用lambda实现同样的效果,这个例子就可以看到lambda的本质了,颤抖吧,小伙伴们:
public class LOLHero {public static void main(String[] args) {Ability ability2 = (token)->{System.out.println("我也只是一个栗子");};}
}
是的,相信你已经看出来了,lambda表达式表达的就是一个匿名内部类,不过不是通过new一个接口或抽象类,而是直接定义里面方法,对,就是匿名方法,来表达一个匿名内部类。所以前面说,lambda表达式就是一种使用匿名内部类的简化方法。不同点在于,匿名内部类使用范围必须是接口和抽象类,且接口和抽象类内可以有n个抽象方法+n个具体方法,但是lambda表达式适用范围仅仅是接口,且接口内只能有1个抽象方法+n个具体方法。没错,这个抽象方法就是你定义的匿名函数。
2、lambda两种使用场景
lambda表达式的使用,是java通过对于上下文语境进行推断,得到接口类型,若发现接口只有一个抽象方法,就可以使用lambda表达式。
第一个场景,形参位置:
public class LOLHero {public static void main(String[] args) {specialFuntion((token)->{System.out.println(token+":万箭齐发。。。。。。");});}public static void specialFuntion(Ability ability){ability.doAbility("寒冰射手");}
}
java可以根据形参的数据类型来推断lambda表达式。在main方法中,我们调用specialFunction方法的时候,要传入一个匿名内部类,由于机智的你发现这个接口只有一个抽象方法,因此我们直接用lambda表达式,直接定义匿名函数,就可以拿到这个匿名内部类,至于接口名,接口抽象方法的形参类型,java都可以推断出来,你就不用填写啦。嗯。。。。也许你会说是,语法糖。。。。嘛。是的,但是像是魔法一样有趣。
运行结果:
寒冰射手:万箭齐发。。。。。。
第二个场景,返回值位置:
public class LOLHero {public static void main(String[] args) {Ability ability1 = getAbility();}public static Ability getAbility(){return (token)->{System.out.println(token+":万箭齐发。。。。。。。。");};}
}
这种情况下,java会根据返回值的数据类型来推断lambda表达式。道理是一样的,java知道要返回一个Ability接口,而该接口仅有一个抽象方法,因此在这里机智的你可以使用lambda表达式来代表一个匿名内部类。
3、lambda使用举例
线程启动
public class LOLHero {public static void main(String[] args) {ScheduledExecutorService es = Executors.newScheduledThreadPool(2);es.scheduleAtFixedRate(()->{System.out.println("我是栗子!");},0,2,TimeUnit.SECONDS);}
}
第一个参数是Rnnable接口,这个接口只有一个抽象方法,因此此处可以使用lambda表达式。
流对象之遍历
机智的你们都知道,在实际使用集合时,最常用的时遍历迭代每一个元素,对每一个元素进行操作。而使用集合的流对象+lambda表达式,可以很方便的做到这一点。
public class LOLHero {public static void main(String[] args) {List<String> heros = new ArrayList<>(Arrays.asList("爱希","蛮王","易大师","皇子","皇子","皇子","我"));heros.stream().forEach(x-> System.out.println(x));}
}
该处,forEach方法中形参是Consumer接口,他有唯一的抽象方法accept(T t),此处lambada表达式就是一个实现了Consumer接口的匿名内部类。遍历结果:
爱希
蛮王
易大师
皇子
皇子
皇子
我
机智的你,想过滤重复的数据,和筛选一定条件的数据,如下:
public class LOLHero {public static void main(String[] args) {List<String> heros = new ArrayList<>(Arrays.asList("爱希","蛮王","易大师","皇子","皇子","皇子","我"));heros.stream().filter(n->n.length() > 1).distinct().forEach(n-> System.out.println(n));}
}
filter方法的形参是Predicate接口,有唯一的抽象方法test(T t),用于筛选长度>1的元素,distinct()进行过滤重复元素,遍历结果如下:
爱希
蛮王
易大师
皇子
流对象之函数式编程
函数式编程的核心是map进行元素转换,reduce进行元素聚合,如下:
public class LOLHero {public static void main(String[] args) {List<String> heros = new ArrayList<>(Arrays.asList("爱希","蛮王","易大师","皇子","皇子","皇子","我"));Integer reduce = heros.stream().map((x) -> x.length()).reduce(0, (sum, x) -> sum + x);System.out.println(reduce);}
}
map方法的形参是Function接口,其有唯一的抽象方法apply(T t),reduce方法的第一个参数是初始值,第二个参数为接口BinaryOperator,其有唯一抽象方法apply(T t,U u),reduce方法会把前面元素的计算结果放在sum位置(第一次放初始值),把下一个元素放在x位置进行聚合操作。该例子中,map将每个元素转化成其长度,用reduce获取其总长度,结果如下:
14
下面还有几个用函数编程的例子,大家可以自行探索:
public class LOLHero {public static void main(String[] args) {List<String> heros = new ArrayList<>(Arrays.asList("爱希","蛮王","易大师","皇子","皇子","皇子","我"));//按一定格式将集合转化成字符串String s = heros.stream().map(x->x+1).collect(Collectors.joining(","));//将集合转化后并获取List<String> list = heros.stream().map(x -> x + x).collect(Collectors.toList());//获取int,long,double的统计对象,可以获取最大值,最小值,平均值,总和等等,十分方便IntSummaryStatistics intSummaryStatistics = heros.stream().map(x -> x.length()).mapToInt(x -> x).summaryStatistics();}
}
总结
说了这么多,其实lambda的本质,还是像开头说的那样,定义一个匿名内部类而已,只要抓住这个关键,使用lambda便是游刃有余啊。
java8新增四大核心函数接口(函数接口,即只有一个抽象函数的接口):
Consumer<T> : 消费型接口(有进无出)void accept(T t);Supplier<T> : 供给型接口(无进有出)T get();Function<T,R> : 函数型接口(有进有出)R apply(T t);Predicate<T> : 断言型接口(有进有出)boolean test(T t);
lambada表达式总结相关推荐
- 2.cocos2dx 3.2中语法的不同之处,lambada表达式的使用和function和bind函数的使用
1 打开建好的T32 Cocos2dx-3.2的一个项目 2 设置Cocos显示窗口的位置是在AppDelegate.cpp中: 3 设置自适应窗口大小的代码是在上面的 ...
- lambada表达式
lambda表达式 //C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作.Lambda的语法形式如下: //[函数对象参数](操作符重载函数参数)mutable或e ...
- Lambada表达式常用案例(技能题)
一:Lambada表达式的结构 1)Lambada表达式的结构我们可以看成三部分 () -> {},箭头左边是参数,右边是执行体,箭头是格式 二:使用案例(List为主的操作) 1)实体对象 @ ...
- lambada表达式介绍
前言 在其他语言中,函数式编程是很常见的,java8中为了支持函数式编程,新增了lambada表达式.lambada表达式其实是匿名内部类和闭包的一种符号表示,至于概念性的问题,大家不必深究,lamb ...
- JDK1.8之Lambada表达式一
一. lambada表达式简介 我们知道对于Java变量可以赋给其一个值,而如果想将"一块代码(一个完整的方法)"赋给一个Java变量,如下所示,怎么做呢? 你可能认为就是下面的方 ...
- Python(十)lambada表达式
一.Lambda 表达式 概念:是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数. ...
- 第十节 Java工具包-Collections 流--lambada表达式
collection为核心的接口,包含了多种不同类型的集合以及多种不同数据结构的实现的类 list set queue都是在collection接口下的所以都有.add()方法 package c ...
- Lambada表达式的用法
Lambada表达式是JDK1.8中最重要的新功能之一.使用Lambada表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类.代码看起来更简洁易懂.Lambada表达式同时还提升了对集合.框架的 ...
- lambada表达式理解
lambada表达式是替换匿名内部类的函数式接口实现类 函数式接口 只有一个抽象方法的接口(可以有默认方法和静态方法),通常带有@FunctionalInterface注解 常用函数式接口 Predi ...
最新文章
- Mac OS X 10.10, Eclipse+ADT真机调试代码时,Device Chooser中不显示真机的解决方式
- [导入]深入了解OpenOffice.org(二){作者:路广}
- 视频云直播:场景、技术及优化
- 尘埃落定,初心未改——一个大学生的电子大赛感悟
- ZOJ3805Machine(二叉树左右子树变换)
- 吴裕雄 15-MySQL LIKE 子句
- 1177: 按要求排序(指针专题)_L2算法基础第10课 排序中
- 【node】---记忆内容
- 我用 Python 抓取了 7000 多本电子书
- 虚幻引擎图文笔记:导入FBX骨骼动画(附官方FBX模型下载)
- 酷派N900刷机教程
- uni-app 点击生成海报
- JAVA:(游戏:四子连)
- iOS开发 学习计划图
- LA 5713 秦始皇修路
- 三轴加速度计得到角度值原理
- 记录一个有关QT生成PDF的过程
- 35 个非常实用的 Shell 拿来就用脚本实例!
- Linux下开启/关闭MySql Server
- SRT字幕的颜色以及一些特效的设置
热门文章
- 5-32 哥尼斯堡的“七桥问题” (25分)
- Android 获得app的应用签名
- 频繁通过win32api的createfile函数打开文件句柄导致内存泄漏
- EDA软件—Cadence学习笔记分享(内含安装教程)
- linux系统命令梳理
- cisco packet tracer配置网络路由
- Goldwasser-Micali 公钥加密系统
- javax.servlet.ServletException: java.lang.NoSuchMethodError 解决方法解决办法
- bazaar android app,Bazaart
- 数字孪生钢厂开发可视化系统-解决方案