JDK8新特性

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Lambda表达式

一:优化性能

先看一段常见的程序

JDK8新特性_字符串

这段程序很简单,但是,会造成性能上的浪费。你看啊,这里调用showLog函数,直接传递1以及mess1和mess2拼接好的字符串传过去,显示Hellojava。但是,如果传递的level是不是1,那么,就不会输出Hellojava,但是,还是会把mess1和mess2拼接好的字符串传递过去。

下来,看一下Lambda表达式写这段程序。

函数式接口IMyLambda

JDK8新特性_java_02

测试类

JDK8新特性_lambda表达式_03

与上面普通方法不同的是:上面的会把拼接字符串mess1 + mess2传给showLog函数;

而使用Lambda表达式,仅仅是把参数传递到showLog方法中,如果第一个参数level是1,才会调用接口IMyLambda中的方法buildMess方法,才会进行字符串的拼接。否则,如果不是1,那么就不会调用接口中的方法,不会进行字符串的拼接。所以,Lambda表达式在一定程度上,优化了程序。


二:书写简单

Lambda表达式和匿名内部类很像,比如:

Lambda表达式写法:

JDK8新特性_java_04

匿名内部类写法:

JDK8新特性_字符串_05

for循环

JDK8新特性_字符串_06

但是,Lambda仅仅适用于函数式接口,所以,在参数为函数式接口的方法中,我们可以尽量使用Lambda表达式,不仅书写简单,还能优化性能。比如,最有名的Runnable接口的run()方法了

三、应用

1.使用lambda表达式实现interface接口

1.1、当一个接口只有一个方法时,可以使用lambda表达式实现这个接口。1.2、当方法中只有一条语句时,可以不写大括号1.3、方法中超过一条语句时,需要写大括号

JDK8新特性_java_07

2.使用lambda表达式实现Runnable接口

JDK8新特性_java_08

3.使用lambda表达式启动一个Thread线程

不用lambda表达式的实现:

JDK8新特性_字符串_09

使用lambda表达式的实现:

JDK8新特性_java_10





Stream API

注意:①Stream自己不会存储元素。②Stream不会改变源对象。相反,会返回持有新结果的新Stream。③Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。


操作的三个步骤:1、创建一个流Stream2、中间操作3、终止操作



filter -- 接受Lambda,从流中排除某些元素

limit -- 截断流,使其元素不超过某个给定数量

skip -- 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit互补。

distinct -- 去重,通过hashcode和equals去重。

JDK8新特性_lambda表达式_11


排序


JDK8新特性_java_12


Stream的终止操作

- allMatch – 检查是否匹配所有元素

- anyMatch – 检查是否至少匹配一个元素

- noneMatch – 检查是否没有匹配所有元素

- findFirst – 返回第一个元素

- count – 返回流中元素的总个数

- max – 返回流中最大值

- min – 返回流中最小值



终止操作:归约reduce

可以将流中的元素反复结合起来,得到一个值


JDK8新特性_lambda表达式_13

终止操作:收集Collect(很强大)

将流转换成其他格式,接受一个Collector接口的实现,用于给Stream中元素做汇总的操作。

Collector接口中方法的实现决定了如何对流进行收集操作(如收集到List、Set、Map)中,Collectors实用类提供了很多静态方法,可以方便的创建常用收集器实例

JDK8新特性_字符串_14


JDK8新特性_lambda表达式_15

map函数的作用就是针对管道流中的每一个数据元素进行转换操作。(映射)

转化大写

JDK8新特性_lambda表达式_16

转化数字

JDK8新特性_字符串_17

处理对象数据格式转换

JDK8新特性_字符串_18

JDK8新特性_lambda表达式_19

由于map的参数e就是返回值,所以可以用peek函数。peek函数是一种特殊的map函数,当函数没有返回值或者参数就是返回值的时候可以使用peek函数。





并行流

1、并行流的效率是否更高

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。

直接使用for循环

JDK8新特性_lambda表达式_20

JDK8的并行流实现(速度快了10倍)

JDK8新特性_lambda表达式_21


2、并行流处理结果是否准确

举个例子来说,遍历打印一个存有0 1 2 3 4 5 6 7 8 9的list,如0 1 2 3 4 5 6 7 8 9

JDK8新特性_java_22

打印的结果如下:

JDK8新特性_lambda表达式_23

并行流

JDK8新特性_字符串_24

打印的结果如下:

JDK8新特性_lambda表达式_25

第二次打印的结果如下:

JDK8新特性_lambda表达式_26

可以看到打印出来的顺序是混乱无规律的。原因是:

并行流内部使用了默认的ForkJoinPool线程池,所以它默认的线程数量就是处理器的数量,通过Runtime.getRuntime().availableProcessors()可以得到这个值。

如果电脑的线程数是12,这意味着并行流最多可以将任务划分为12个小模块进行处理,然后再合并计算得到结果。

打印处理的时候为了提高效率,不分先后顺序,故而造成打印的乱序。


并行流的实现机制:

JDK8新特性_lambda表达式_27


结论:

当需要遍历的数据,存在强顺序性时,不能使用并行流,如顺序打印0~9;不要求顺序性时,可以使用并行流以提高效率,如将集合中的字符串中的"a"替换成"b"。




Optional类

Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用null 表示一个值不存在,现在Optional 可以更好的表达这个概念。并且可以避免空指针异常


常用方法:

- Optional.of(T t) : 创建一个Optional 实例

- Optional.empty() : 创建一个空的Optional 实例

- Optional.ofNullable(T t):若t 不为null,创建Optional 实例,否则创建空实例

- isPresent() : 判断是否包含值

- orElse(T t) : 如果调用对象包含值,返回该值,否则返回t

- orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回s 获取的值

- map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()

- flatMap(Function mapper):与map 类似,要求返回值必须是Optional


JDK8新特性_字符串_28


JDK8新特性_lambda表达式_29

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6