司内小分享, boss让我整理一下JAVA8新特性, 噢噢噢噢!!!还有这好事儿, 正好趁着这个机会好好学习下、基于我不写笔记学不下去的习惯(分享也要有文档), 就出现了本篇内容、主要讲使用条件和方式, 原理请自行Google
上篇: Lambda表达式, Collector, Optional
下篇: Stream流, LocalDateTime
说明: 测试中生成box测试数据均为一下方法生成
public static List
函数式编程: 允许把函数作为基本运算单元, 可以作为方法的参数,又称闭包.
方法引用: 是指如果某个方法签名和接口恰好一致(只看参数类型和返回类型,不看方法名称,也不看类的继承关系),就可以直接传入方法引用。
函数式接口: 有且只有一个必须实现方法的接口(由于JAVA8中接口可以有了默认实现, 所以定义了一个 @FunctionalInterface 注解作为函数式接口的标记)
如:Comparator、Runnable以及四大函数式接口Consumer(返回void)、Function(返回映射泛型)、Predicate(返回boolean)、Supplier(返回定义的泛型)
Lambda表达式可以直接访问外部域变量, 但只能引用标记了 final 的外层局部变 量,不能lambda 内部修改定义在域外的局部变量.方法引用
如果某个方法签名和接口恰好一致,就可以直接传入方法引用四大函数式接口
简单的讲就是四类函数容器(容器的概念和思想很重要啊) 1.3 格式
Lambda表达式: “->”
方法引用: “::”
可选类型声明: 不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号: 一个参数无需定义圆括号,但无参数或者多个参数需要定义圆括 号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需 要指定表达式返回了一个数值。方法引用
1)在使用lambda表达式时, 如果匿名函数的返回值类型和参数类型都已经确定, 则可以将任何符合要求的方法以方法引用的方式传入
2)第一不关心方法名; 第二不关心类的继承关系; 第三不关心方法实现 1.5 案例
以数组、集合排序为例
Lambdaprivate static void lambda() { System.out.println("源数据boxes_1:"); List
public static int ohMyGod(Integer num1, Integer num2) {// 为了与原数字排序方式混淆, 此处使用倒序排序 return num2 - num1;}private static void methodReference() { Integer[] numbers = {5, 8, 2, 3, 4, 1, 9, 0}; Arrays.sort(numbers, LambdaDemo::ohMyGod);// Arrays.sort(numbers, Math::max); System.out.println(Arrays.toString(numbers));}
如上: ohMyGod的方法返回值和参数与compare方法一致, 此处就可以使用方法引用, Math的max方法也符合要求, 也可以使用、这两个方法名字, 继承和实现关系, 方法实现都不相同, 但不影响使用.
二、Collector和Collectors 2.1 描述 Collector: 可变的聚合操作, 定义一个可变容器, 将新输入的元素添加到可变容器中(可以认为是可变容器的操作容器)
Collectors: 收集器工具类, 定义部分常用收集器
有三个泛型:
T: 元素类型
A: 可变容器类型
R: 结果容器类型
有五个方法:
Supplier: 创建新的结果容器
Accumulator: 合并元素到结果容器中
Combiner: 合并两个结果容器
Finisher: 将结果容器转为最终表示
Characteristics: 给collector设置特征值
工作原理即使用Collector中定义的方法对内容进行可达到目的性的操作
2.3 特征 有三个特征值:
CONCURRENT: 表示结果容器只有一个
UNORDERED: 表示流中的元素无序
IDENTITY_FINISH: 表示中间结果容器类型与最终结果类型一致
Collector
自定义一个实现public class MyCollector
public static
private static void myCollector() {// 创建一个数组和一个集合, 进行操作 String[] strings = {"a", "b", "c", "d"}; List
Collectors
工具集不做过多介绍
常用的方法: toXxx, groupBy, joining, reducing等
大部分的容器操作都可以通过下篇的Stream流实现 三、Optional 3.1 描述
容器对象, 容器中的值可以为null
定义对象检测方法和对象处理方法, 用于进行对象检测(空值检测), 空值问题的解决方 案
Optional.of: 不允许为null 值的创建方式, 会报空指针异常
Optional.ofNullable: 允许为null 值的创建方式
Optional.empty: 值为null 的创建方式(Optional内部维护的空值对象)
Optional
orElse: 当前处理容器中的Optional值为null时, 则将orElse的参数作为返回值
orElseGet: 当前处理容器中的Optional值为 null时, 则将orElseGet中定义的方法返回值作为方法返回值
orElseThrow: 当前处理容器中的Optional值为null时, 则将orElseThrow中定义的方法返回的异常抛出
private static void orElse() { Box b = null; Box box1 = Optional.ofNullable(b).orElse(new Box().setName("1")); Box box2 = Optional.ofNullable(b).orElseGet(() -> new Box().setName("2")); Box box = Optional.ofNullable(b).orElseThrow(() -> new RuntimeException("box 不存在!"));}
映射值map: 根据参数定义的函数, 获取值对象的相应映射值, 创建映射值的Optional容器并返回
flagMap: 参数定义的函数的返回值必须是Optional容器, 方法的返回值结果都已映射值对象的Optional容器
Optional
isPresent: 判断空值
ifPresent: 判断空值, 在判断不为null时进行处理操作
Optional
filter: 对容器中的值进行过滤; 如果存在值符合条件, 则返回这个Optional容器, 如果不存在, 返回Optional的empty对象
double random = Math.random() * 10;Optional
空指针解决方案演示:
User user = new User();String s = Optional.ofNullable(user) .map(User::getAddress)// .orElse(new Address()) .map(Address::getProvince)// .orElseGet(Province::new) .flatMap((p -> { City city = new City(); p.setCity(city); return Optional.of(city); })) .map(City::getStreet) .orElseThrow(() -> new RuntimeException("容器中值为 null"));
方式一: 添加默认值的方式
方式二: 抛异常的方式(map方法在某次返回empry之后, 后续的所有操作都是对 empry的操作, 除非使用flatMap进行手动创建新的数据容器)
日 期 : 2022 − 02 − 12 color{#00FF00}{日期:2022-02-12} 日期:2022−02−12