Java 8 Lambda 表达式

一、函数式编程特性

1、函数是"第一等公民" 

什么是"第一等公民"?所谓"第一等公民"(first class),指的是函数与其他数据类型一样,处于平等地位,它不仅拥有一切传统函数的使用方式(声明和调用),可以赋值给其他变量(赋值),也可以作为参数,传入另一个函数(传参),或者作为别的函数的返回值(返回)。函数可以作为参数进行传递,意味我们可以把行为"参数化",处理逻辑可以从外部传入,这样程序就可以设计得更灵活。

2、没有"副作用"

所谓"副作用"(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

3、引用透明

引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。

 

二、函数式编程优点

1、代码简洁,开发快速。

函数式编程大量使用函数,减少了代码的重复,因此程序比较短,开发速度较快。

2. 接近自然语言,易于理解

函数式编程的自由度很高,可以写出很接近自然语言的代码。以java为例把学生以性别分组:

没用labmda表达式: 

用了lambda表达式:

这基本就是自然语言的表达了,大家应该一眼就能明白它的意思吧。 

 

三、Lambda表达式的组成

java 8 中Lambda 表达式由三个部分组成:第一部分为一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数;第二部分为一个箭头符号:->;第三部分为方法体,可以是表达式和代码块。语法如下:

1、方法体为表达式,该表达式的值作为返回值返回。

  2、方法体为代码块,必须用 {} 来包裹起来,且需要一个 return 返回值,但若函数式接口里面方法返回值是 void,则无需返回值。

 

四、Lambda表达式的应用场景

1、使用() -> {} 替代匿名类

我们看到相对而言Lambda表达式要比匿名类要优雅简洁很多~。

2、以流水线的方式处理数据

借助stream api和Lambda表达式,以住需要定义多个变量,编写数十行甚至数百行的代码的集合操作,现在都基本简化成了可以在一行之内完成~

3、更简单的数据并行处理

数据并行处理,只需要在原来的基础上加一个parallel()就可以开启~。顺便提一下这里parallel()开启的底层并行框架是fork/join,默认的并行数是Ncpu个。

4、用内部迭代取代外部迭代

外部迭代:描述怎么干,代码里嵌套2个以上的for循环的都比较难读懂;只能顺序处理List中的元素;

内部迭代:描述要干什么,而不是怎么干;不一定需要顺序处理List中的元素

5、重构现有臃肿代码,更高的开发效率

在Lambda表达式出现之前,我们的处理逻辑只能是以命令式编程的方式来实现,需要大量的代码去编写程序的每一步操作,定义非常多的变量,代码量和工作量都相对的巨大。如果用Lambda表达式我们看到以往数十行甚至上百行的代码都可以浓缩成几行甚至一行代码。这样处理逻辑就会相对简单,开发效率可以得到明显提高,维护工作也相对容易。

 

五、Lambda表达式中的Stream

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

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

Stream可以有限的也可以是无限的,流的构造方式有很多可以从常用的Collection(List,Array,Set and so on...),文件,甚至函数....

由值创建流:

               Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");

由数组创建流: 

               int[] numbers = {2, 3, 5, 7, 11, 13}; int sum = Arrays.stream(numbers).sum();       

由文件创建流

               Stream<String> lines =Files.lines(Paths.get("data.txt"), Charset.defaultCharset())

上面的这些Stream都是有限的,我们可以用函数来创建一个无限Stream

              Stream.iterate(0, n -> n + 2).forEach(System.out::println);

Stream也很懒惰,它只会在你真正需要数据的时候才会把数据给传给你,在你不需要时它一个数据都不会产生。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值