前言

作为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表达式总结相关推荐

  1. 2.cocos2dx 3.2中语法的不同之处,lambada表达式的使用和function和bind函数的使用

    1        打开建好的T32  Cocos2dx-3.2的一个项目 2        设置Cocos显示窗口的位置是在AppDelegate.cpp中: 3  设置自适应窗口大小的代码是在上面的 ...

  2. lambada表达式

     lambda表达式 //C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作.Lambda的语法形式如下: //[函数对象参数](操作符重载函数参数)mutable或e ...

  3. Lambada表达式常用案例(技能题)

    一:Lambada表达式的结构 1)Lambada表达式的结构我们可以看成三部分 () -> {},箭头左边是参数,右边是执行体,箭头是格式 二:使用案例(List为主的操作) 1)实体对象 @ ...

  4. lambada表达式介绍

    前言 在其他语言中,函数式编程是很常见的,java8中为了支持函数式编程,新增了lambada表达式.lambada表达式其实是匿名内部类和闭包的一种符号表示,至于概念性的问题,大家不必深究,lamb ...

  5. JDK1.8之Lambada表达式一

    一. lambada表达式简介 我们知道对于Java变量可以赋给其一个值,而如果想将"一块代码(一个完整的方法)"赋给一个Java变量,如下所示,怎么做呢? 你可能认为就是下面的方 ...

  6. Python(十)lambada表达式

    一.Lambda 表达式 概念:是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数. ...

  7. 第十节 Java工具包-Collections 流--lambada表达式

     collection为核心的接口,包含了多种不同类型的集合以及多种不同数据结构的实现的类 list  set queue都是在collection接口下的所以都有.add()方法 package c ...

  8. Lambada表达式的用法

    Lambada表达式是JDK1.8中最重要的新功能之一.使用Lambada表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类.代码看起来更简洁易懂.Lambada表达式同时还提升了对集合.框架的 ...

  9. lambada表达式理解

    lambada表达式是替换匿名内部类的函数式接口实现类 函数式接口 只有一个抽象方法的接口(可以有默认方法和静态方法),通常带有@FunctionalInterface注解 常用函数式接口 Predi ...

最新文章

  1. Mac OS X 10.10, Eclipse+ADT真机调试代码时,Device Chooser中不显示真机的解决方式
  2. [导入]深入了解OpenOffice.org(二){作者:路广}
  3. 视频云直播:场景、技术及优化
  4. 尘埃落定,初心未改——一个大学生的电子大赛感悟
  5. ZOJ3805Machine(二叉树左右子树变换)
  6. 吴裕雄 15-MySQL LIKE 子句
  7. 1177: 按要求排序(指针专题)_L2算法基础第10课 排序中
  8. 【node】---记忆内容
  9. 我用 Python 抓取了 7000 多本电子书
  10. 虚幻引擎图文笔记:导入FBX骨骼动画(附官方FBX模型下载)
  11. 酷派N900刷机教程
  12. uni-app 点击生成海报
  13. JAVA:(游戏:四子连)
  14. iOS开发 学习计划图
  15. LA 5713 秦始皇修路
  16. 三轴加速度计得到角度值原理
  17. 记录一个有关QT生成PDF的过程
  18. 35 个非常实用的 Shell 拿来就用脚本实例!
  19. Linux下开启/关闭MySql Server
  20. SRT字幕的颜色以及一些特效的设置

热门文章

  1. 5-32 哥尼斯堡的“七桥问题” (25分)
  2. Android 获得app的应用签名
  3. 频繁通过win32api的createfile函数打开文件句柄导致内存泄漏
  4. EDA软件—Cadence学习笔记分享(内含安装教程)
  5. linux系统命令梳理
  6. cisco packet tracer配置网络路由
  7. Goldwasser-Micali 公钥加密系统
  8. javax.servlet.ServletException: java.lang.NoSuchMethodError 解决方法解决办法
  9. bazaar android app,Bazaart
  10. 数字孪生钢厂开发可视化系统-解决方案