Java8 lambda表达式存在的意义及使用示例

本贴最后更新于 2772 天前,其中的信息可能已经水流花落
Lambda表达式有这么重要的两点
1. Lambda表达式是一个很小且能被当作数据进行传递的函数。
2. 集合对象在内部的遍历方式,这种遍历不同于当前已有的外部顺序化遍历。


###1. 内部循环和外部循环的区别
先举个例子
```
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);  
for (int number : numbers) {  
    System.out.println(number);  
} 
```
这就是外部循环的写法,这样写有什么缺点呢,有这么几个:
>* 只能顺序处理List中的元素(process one by one)
>* 不能充分利用多核CPU
>* 不利于编译器优化
而如果用内部循环,写成这样:
```
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);  
numbers.forEach((Integer value) -> System.out.println(value)); 
```

这种内部循环的写法,能带来这么几个好处:
>* 不一定需要顺序处理List中的元素,顺序可以不确定
>* 可以并行处理,充分利用多核CPU的优势
>* 有利于JIT编译器对代码进行优化

###2. 为什么你需要Lambda表达式
有了上面的对比,很清晰的就能知道为什么需要lambda表达式了。
很多时候,我们希望集合能够执行如下一种或几种操作:
1. 创建一个新的集合对象,但要过滤掉不符合条件的元素。
2. 对集合中的元素逐一进行转化,并使用转化后的集合。
3. 创建集合中所有元素的某个属性的总体值,例如,合计值与平均值。这样的任务(分别称之为过滤,映射和化简)具有共通的要点:它们都需要处理集合中的每个元素。

程序无论是判定某个元素是否存在,或是判断元素是否符合某个条件(过滤),或是将元素转化成新元素并生成新集合(映射),或是计算总体值(化简),关键原理就是"程序必须处理到集合中的每个元素"。
这就暗示我们需要一种简单的途径去表示用于内部遍历的程序。在Groovy中,就有提供这么完备的集合操作,他是通过闭包的方式来写:举个例子
collect方法–对集合每个元素进行运算后,得到一个新集合
```
def list = [1, 2, 3, 4]
def result = list.collect{it*2}
```
过滤–筛选出符合条件的元素,生成一个新集合
```
def list = [1, 2, 3, 4]
def result = list.grep{ it > 2 }
println result
```
看到这样书写给开发带来了很大的便利。所以java 8也提供了lambda的实现

那lambda的优点,总结出来就有这么几点:
####2.1 更紧凑的代码
Lambda表达式以一种简洁的方式去实现仅有一个方法的Java类。
如果代码中有大量的匿名内部类--诸如用于UI应用中的监听器与处理器实现,以及用于并发应用中的Callable与Runnable实现--在使用了Lambda表达式之后,将使代码变得非常短,且更易于理解。

####2.2. 通过提供额外的功能对方法的功能进行修改的能力
有时,方法不具备我们想要的一些功能。例如,Collection接口中的contains()方法只有当传入的对象确实存在于该集合对象中时才会返回true。但我们无法去干预该方法的功能,比如,若使用不同的大小写方案也可以认为正在查找的字符串存在于这个集合对象中,我们希望此时contains()方法也能返回true。

简单点儿说,我们所期望做的就是"将我们自己的新代码传入"已有的方法中,然后再调用这个传进去的代码。Lambda表达式提供了一种很好的途径来代表这种被传入已有方法且应该还会被回调的代码。
####2.3. 更好地支持多核处理
当今的CPU具备多个内核。这就意味着,多线程程序能够真正地被并行执行,这完全不同于在单核CPU中使用时间共享这种方式。通过在Java中支持函数式编程语法,Lambda表达式能帮助你编写简单的代码去高效地应用这些CPU内核。

例如,你能够并行地操控大集合对象,通过利用并行编程模式,如过滤、映射和化简(后面将会很快接触到这些模式),就可使用到CPU中所有可用的硬件线程。

###3. Lambda表达式的语法规则
Lambda表达式的基本格式是以一个可被接受的`参数列表`开头,以一些代码(称之为`表达式体/body`)结尾,并以`箭头(->)`将前两者分隔开。
例如:
```
Arrays.sort(dogArray, (Dog m, Dog n) -> m.getWeight() - n.getWeight());
printDogs(dogArray);
```

###4. Stream
Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。

而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的 `Fork/Join` 框架(JSR166y)来拆分任务和加速处理过程。

**流的构成**
当我们使用一个流的时候,通常包括三个基本步骤:
获取一个数据源(source)→ 数据转换→执行操作获取想要的结果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道

使用举例
1. 挑出偶数
```
Integer[] sixNums = {1, 2, 3, 4, 5, 6};
Integer[] evens = Stream.of(sixNums).filter(n -> n%2 == 0).toArray(Integer[]::new);
```

2.把单词挑出来
```
List<String> output = reader.lines().
flatMap(line -> Stream.of(line.split(REGEXP))).
filter(word -> word.length() > 0).
collect(Collectors.toList());
```
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3165 引用 • 8206 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
guobing
会当凌绝顶,一览众山小 北京

推荐标签 标签

  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 7 关注
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 676 关注
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 339 关注
  • 反馈

    Communication channel for makers and users.

    123 引用 • 906 回帖 • 177 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    238 引用 • 224 回帖
  • 分享

    有什么新发现就分享给大家吧!

    240 引用 • 1729 回帖
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    124 引用 • 580 回帖
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    37 引用 • 24 回帖 • 1 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 41 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    19 引用 • 22 回帖 • 675 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    126 引用 • 1699 回帖
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    198 引用 • 120 回帖
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 549 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 383 回帖
  • CodeMirror
    1 引用 • 2 回帖 • 108 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 380 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 124 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    171 引用 • 988 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 125 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖 • 2 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    529 引用 • 3527 回帖 • 1 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖 • 2 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 171 关注
  • 七牛云

    七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化 PaaS 服务。围绕富媒体场景,七牛先后推出了对象存储,融合 CDN 加速,数据通用处理,内容反垃圾服务,以及直播云服务等。

    25 引用 • 215 回帖 • 161 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 689 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 56 关注