一篇学会Java8新特性

在这里插入图片描述

  1. 函数式接口
  2. lambda
  3. 新增方法举类
  4. Stream
  5. 接口默认方法
  6. DATE API

优点:
1.代码简洁,开发快速: 函数式编程大量使用函数,减少了代码的重复,因此程序比较短,开发速度较快
2. 接近自然语言,易于理解
3. 更方便的代码管理: 函数式编程不依赖、也不会改变外界的状态,只要给定输入参数,返回的结果必定相同
4. 易于“并发编程”:因为它不修改变量,所以根本不存在"锁"线程的问题
Lambda 表达式
Lambda 表达式将函数当成参数传递给某个方法,或者把代码本身当作数据处理;

函数式接口

函数式接口在java中是指:有且仅有一个抽象方法的接口
函数式接口,即适用于函数式编程场景的接口。而java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。
如果自定义一个函数式接口尽量使用 @FunctionalInterface 函数式接口声明来说这就是一个函数式接口,别动了。
在这里插入图片描述

lambda语法格式

表达式的组成:
1.形参
2. 箭头符号 ->
3.方法体
在这里插入图片描述

自定义一个函数式接口,等下来用例子看一下它的四种语法
在这里插入图片描述
在这里插入图片描述
其中Interger::sum为方法引用,后面会讲。

注意事项

lambda 表达式只能引用标记了 final 的外层局部变量,不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。可以不使用final关键字,但是必须不可被后面的代码修改
在这里插入图片描述
编译器给的异常描述:
在这里插入图片描述

不允许声明一个与局部变量同名的参数或者局部变量
在这里插入图片描述

基本函数式接口

在实际使用中很少使用自定义函数式接口,java8中的util.function包中包含了大部分常用接口,
这些接口都是以下面四种基本函数式接口为基础的。
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

新方法使用

在这里插入图片描述

foreach

API
在这里插入图片描述
源码:
源码中十一用迭代器以及四大基本类型中Consumer类型
在这里插入图片描述

使用示例
在这里插入图片描述
在这里插入图片描述

removeIf

API
在这里插入图片描述
源码
源码中是使用迭代器,去匹配每个符合条件的地址,然后去除
在这里插入图片描述
例子
在这里插入图片描述

Map中新增方法示例

foreach

API
在这里插入图片描述
源码
源码中也是使用迭代器以及Biconsumer基本函数式接口来实现的
在这里插入图片描述
这个基本函数式接口的代码:
在这里插入图片描述
例子
有两个参数,第一个参数是map的key,第二个参数是map的value;
在这里插入图片描述

还有map中一些大家常用的方法也加入到了里面,
根据key在map中获取,获取到的值为空返回默认值;
在这里插入图片描述
如果map中存在该value就不覆盖
在这里插入图片描述

根据KEY和value来判断是否删除该值
在这里插入图片描述
如果该键值对存在,替换在这里插入图片描述
根据KEY和value来判断是否替换
在这里插入图片描述

Stream

Stream类似一个高级的迭代器,单向,不可往复,数据只能遍历一遍,用户只要给出对其包涵的元素执行什么操作,Stream会隐式地在内部进行遍历做对应的操作。

特性

  • 无存储。

stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。

  • 为函数式编程而生。

对stream的任何修改都不会修改背后的数据源,比如对stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新stream。

  • 惰式执行。

stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。

  • 可消费性。

stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

中间操作(intermediate operations)和结束操作(terminal operations),

二者特点是:
中间操作总是会惰式执行
调用中间操作只会生成一个标记了该操作的新stream,仅此而已。
结束操作会触发实际计算
计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。

      区分中间操作和结束操作最简单的方法,就是看方法的返回值,返回值为stream的大都是中间操作,否则是结束操作。

在这里插入图片描述
示例
在这里插入图片描述
在这里插入图片描述
list.stream.foreach等同于list.foreach
在这里插入图片描述
过滤和去重
在这里插入图片描述

收集器(Collector)
是为Stream.collect()方法量身打造的工具接口(类)。
考虑一下将一个Stream转换成一个容器(或者Map)需要做哪些工作?
1:目标容器是什么?是ArrayList还是HashSet,或者是个TreeMap。
2:新元素如何添加到容器中?是List.add()还是Map.put()。
3:如果并行的进行规约,还需要告诉collect() 多个部分结果如何合并成一个。
在这里插入图片描述
在这里插入图片描述

使用自带方法讲stream转为list,toList返回类型ArrayList,toSet返回类型为HashSet

在这里插入图片描述

映射

Stream背后依赖于某种数据源,数据源可以是数组、容器等,但不能是Map,
使用collect 生成Map方式
使用Collectors.toMap()生成的收集器,用户需要指定如何生成Map的key和value
使用Collectors.partitioningBy()生成的收集器,对元素进行二分区操作
使用Collectors.groupingBy()生成的收集器,对元素做group操作

在这里插入图片描述
Function.identity()返回一个输出跟输入一样的Lambda表达式对象,等价于形如t -> t形式的Lambda表达式。

使用partitioningBy()生成的收集器,这种情况适用于将Stream中的元素依据某个二值逻辑(满足条件,或不满足)
分成互补相交的两部分,比如男女性别、成绩及格与否等。下列代码展示将学生分成成绩及格或不及格的两部分。
在这里插入图片描述

map用法
在这里插入图片描述flagMap示例
在这里插入图片描述
在这里插入图片描述
map与flagMap区别

在执行map操作以后,我们得到是一个包含多个字符串(构成一个字符串的字符数组)的流,此时执行distinct操作是基于在这些字符串数组之间的对比,所以达不到我们希望的目的,此时的输出为:
j, a, v, a, 8] [i, s] [e, a, s, y] [t, o] [u, s, e]

在这里插入图片描述

结果正确

flatMap将由map映射得到的Stream<String[]>,转换成由各个字符串数组映射成的流Stream,再将这些小的流扁平化成为一个由所有字符串构成的大流Steam,从而能够达到我们的目的。

接口的默认方法

Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,示例如下:
在这里插入图片描述
Formula接口在拥有calculate方法之外同时还定义了sqrt方法,实现了Formula接口的子类只需要实现一个calculate方法,默认方法sqrt将在子类上可以直接使用。
在这里插入图片描述

Date API

Java 8 在包java.time下包含了一组全新的时间日期API。新的日期API和开源的Joda-Time库差不多,但又不完全一样,下面的例子展示了这组新API里最重要的一些部分:

Clock 时钟

Clock类提供了访问当前日期和时间的方法,Clock是时区敏感的,可以用来取代 System.currentTimeMillis() 来获取当前的微秒数。某一个特定的时间点也可以使用Instant类来表示,Instant类也可以用来创建老的java.util.Date对象。
在这里插入图片描述
Timezones 时区

在新API中时区使用ZoneId来表示。时区可以很方便的使用静态方法of来获取到。 时区定义了到UTS时间的时间差,在Instant时间点对象到本地日期对象之间转换的时候是极其重要的。

在这里插入图片描述
LocalTime 本地时间

LocalTime 定义了一个没有时区信息的时间,例如 晚上10点,或者 17:30:15。下面的例子使用前面代码创建的时区创建了两个本地时间。之后比较时间并以小时和分钟为单位计算两个时间的时间差:

在这里插入图片描述
LocalTime 提供了多种工厂方法来简化对象的创建,包括解析时间字符串。

在这里插入图片描述
LocalDate 本地日期
LocalDate 表示了一个确切的日期,比如 2014-03-11。该对象值是不可变的,用起来和LocalTime基本一致。下面的例子展示了如何给Date对象加减天/月/年。另外要注意的是这些对象是不可变的,操作返回的总是一个新实例。

在这里插入图片描述
从字符串解析一个LocalDate类型和解析LocalTime一样简单:
在这里插入图片描述

LocalDateTime 本地日期时间

LocalDateTime 同时表示了时间和日期,相当于前两节内容合并到一个对象上了。LocalDateTime和LocalTime还有LocalDate一样,都是不可变的。LocalDateTime提供了一些能访问具体字段的方法。
在这里插入图片描述
只要附加上时区信息,就可以将其转换为一个时间点Instant对象,Instant时间点对象可以很容易的转换为老式的java.util.Date。

在这里插入图片描述
格式化LocalDateTime和格式化时间和日期一样的,除了使用预定义好的格式外,我们也可以自己定义格式:
在这里插入图片描述
和java.text.NumberFormat不一样的是新版的DateTimeFormatter是不可变的,所以它是线程安全的。
关于时间日期格式的详细信息:http://download.java.net/jdk8/docs/api/java/time/format/DateTimeFormatter.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值