jdk8新特性

jdk8新特性学习,视频来自2021最新版JDK8新特性详解

一、Lambda表达式

lambda表达式的优点:
1、简化匿名内部类的使用
lambda表达式:匿名内部类是传入接口,而且该接口只能有一个抽象方法
一个方法传入接口,就是匿名内部类的写法,因为必须实现接口的抽象方法,否则会报错

2、lambda表达式的省略写法
image.png

3、lambda表达式的使用前提
image.png
4、lambda表达式和匿名内部类的对比
image.png

Lambda表达式使用时不关心接口名,抽象方法名。只关心抽象方法的参数列表和返回值类型

二、接口新特性

1、默认方法 default void test()
接口中的抽象方法一定要重写,如果有默认方法存在。多个实现了接口的类,可以不重写默认方法
2、静态方法
直接通过接口类名调用

3、两者的区别介绍
image.png

三、函数式接口

1、函数式接口的由来
lambda表达式只关心入参和返回值类型,重写接口中的方法,lambda表达式相当于一个实现类
2、函数式接口介绍
String.valueOf 将其他类型转为String
Double.valueOf 将字符串转为Double
Arrays.sort() 对数组进行排序
image.png
image.png
image.png
image.png

image.png

jdk提供了以上四种函数式接口,我们就不用自己再去写接口了

四、方法引用

image.png
image.png
对象名::方法名
类名::静态方法名
类名::方法名
类名::构造器
数组::构造器

image.png

五、Stream API

定义一个List集合 Arrays.asList() 主要针对集合的操作进行优化

常用API

集合数据处理举例:
image.png

Stream对数据进行加工处理,filter、map、skip、count

image.png

image.png

stream要调用终结方法才有作用
image.png
image.png
** 4.3 filter**
image.png
image.png

4.5 skip
image.png
image.png
4.7 sorted
image.png
o2 - o1 代表降序 sorted默认是升序
image.png
image.png
image.png
image.png
image.pngimage.png
image.png
image.png
-> 叫做箭头

4.13 map与reduce的结合
image.png

stream对包装类进行操作i,比如Integer

Integer.intValue 把String转为int

4.14 mapToInt
image.png
image.png
image.png

4.16 综合案例

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.bobo.jdk.stream;
import com.bobo.jdk.lambda.domain.Person;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamTest21Demo {
/**
* 1. 第一个队伍只保留姓名长度为3的成员
* 2. 第一个队伍筛选之后只要前3个人
* 3. 第二个队伍只要姓张的成员
* 4. 第二个队伍筛选之后不要前两个人
* 5. 将两个队伍合并为一个队伍
* 6. 根据姓名创建Person对象输出结果:
5.Stream结果收集
5.1 结果收集到集合中
* 7. 打印整个队伍的Person信息
* @param args
*/
public static void main(String[] args) {
List<String> list1 = Arrays.asList("迪丽热巴", "宋远桥", "苏星河", "老子",
"庄子", "孙子", "洪七 公");
List<String> list2 = Arrays.asList("古力娜扎", "张无忌", "张三丰", "赵丽颖",
"张二狗", "张天爱", "张三");
// 1. 第一个队伍只保留姓名长度为3的成员
// 2. 第一个队伍筛选之后只要前3个人
Stream<String> stream1 = list1.stream().filter(s -> s.length() ==
3).limit(3);
// 3. 第二个队伍只要姓张的成员
// 4. 第二个队伍筛选之后不要前两个人
Stream<String> stream2 = list2.stream().filter(s ->
s.startsWith("张")).skip(2);
// 5. 将两个队伍合并为一个队伍
// 6. 根据姓名创建Person对象
// 7. 打印整个队伍的Person信息
Stream.concat(stream1,stream2)
//.map(n-> new Person(n))
.map(Person::new)
.forEach(System.out::println);
}
}

想要test测试,可以引入 junit 依赖

Stream结果收集

image.png
聚合运算:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/
**
* Stream流中数据的聚合计算
*/
@Testpublic void test03(){
// 获取年龄的最大值
Optional<Person> maxAge = Stream.of(
new Person("张三", 18)
, new Person("李四", 22)
, new Person("张三", 13)
, new Person("王五", 15)
, new Person("张三", 19)
).collect(Collectors.maxBy((p1, p2) -> p1.getAge() - p2.getAge()));
System.out.println("最大年龄:" + maxAge.get());
// 获取年龄的最小值
Optional<Person> minAge = Stream.of(
new Person("张三", 18)
, new Person("李四", 22)
, new Person("张三", 13)
, new Person("王五", 15)
, new Person("张三", 19)
).collect(Collectors.minBy((p1, p2) -> p1.getAge() - p2.getAge()));
System.out.println("最新年龄:" + minAge.get());
// 求所有人的年龄之和
Integer sumAge = Stream.of(
new Person("张三", 18)
, new Person("李四", 22)
, new Person("张三", 13)
, new Person("王五", 15)
, new Person("张三", 19)
)
//.collect(Collectors.summingInt(s -> s.getAge()))
.collect(Collectors.summingInt(Person::getAge))
;
System.out.println("年龄总和:" + sumAge);
// 年龄的平均值
Double avgAge = Stream.of(
new Person("张三", 18)
, new Person("李四", 22)
, new Person("张三", 13)
, new Person("王五", 15)
, new Person("张三", 19)
).collect(Collectors.averagingInt(Person::getAge));
System.out.println("年龄的平均值:" + avgAge);
// 统计数量
Long count = Stream.of(
new Person("张三", 18)
, new Person("李四", 22)
, new Person("张三", 13)
, new Person("王五", 15)
, new Person("张三", 19)
).filter(p->p.getAge() > 18)
.collect(Collectors.counting());
System.out.println("满足条件的记录数:" + count);
}

数组分组:
image.png
image.png
image.png
image.png
image.png
image.png
image.png

并行的Stream流

之前的Stream操作都是串行流,它们都是在一个线程中去操作,因此效率不是很高

获取并行流的两种方式:
image.png
并行流就是转换成多线程处理
image.png

并行流中的线程安全问题
image.png
image.png

六、Optional类

解决空指针问题
image.png
image.png
image.png

Optional常用方法

image.png
image.png

七、新日期时间API

sdf.format 将时间转为字符串
sdf.parse 将字符串转为时间

想要不打印错误日志,可以 try catch 打印一下,可以把错误信息提示去除
image.png

新的API位于java.time包下

新日期API介绍

image.png
日期时间类型:
image.png
image.png
image.png
LocalDate、LocalTime、LocalDateTime的操作

日期时间的修改和比较

image.png
image.png
变量后加soutv,可以快速打印,并且是v = 的形式
image.png
新日期API在多线程场景下是日期安全的,因为他创建了一个新对象,不是在原对象基础上修改的

日期格式化

image.png
image.png
image.png
image.png

image.png
使用方法引用打印更加的简洁
image.png
image.png

八、其他新特性

image.png
image.png