当前位置 : 主页 > 编程语言 > java >

JDK8新特性

来源:互联网 收集:自由互联 发布时间:2023-02-04
Lambda表达式 一:优化性能 先看一段常见的程序 这段程序很简单,但是,会造成性能上的浪费。你看啊,这里调用showLog函数,直接传递1以及mess1和mess2拼接好的字符串传过去,显示Hel

Lambda表达式

一:优化性能

先看一段常见的程序

JDK8新特性_字符串

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

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

函数式接口IMyLambda

JDK8新特性_java_02

测试类

JDK8新特性_java_03

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

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

二:书写简单

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

Lambda表达式写法:

JDK8新特性_字符串_04

匿名内部类写法:

JDK8新特性_java_05

for循环

JDK8新特性_java_06

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

三、应用

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

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

JDK8新特性_java_07

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

JDK8新特性_字符串_08

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

不用lambda表达式的实现:

JDK8新特性_lambda表达式_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新特性_字符串_11

排序

JDK8新特性_lambda表达式_12

Stream的终止操作

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

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

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

- findFirst – 返回第一个元素

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

- max – 返回流中最大值

- min – 返回流中最小值

终止操作:归约reduce

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

JDK8新特性_lambda表达式_13

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

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

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

JDK8新特性_java_14

JDK8新特性_lambda表达式_15

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

转化大写

JDK8新特性_lambda表达式_16

转化数字

JDK8新特性_字符串_17

处理对象数据格式转换

JDK8新特性_java_18

JDK8新特性_字符串_19

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

并行流

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

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

直接使用for循环

JDK8新特性_java_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新特性_字符串_22

打印的结果如下:

JDK8新特性_字符串_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新特性_java_28

JDK8新特性_字符串_29

上一篇:【学懂Java】(四)面向对象编程-3
下一篇:没有了
网友评论