相关链接
数据准备
通过案例,使用Optional对模拟数据进行一系列处理,熟悉Optional各常用方法
1. pom.xml 配置文件 参考笔记 -> 六、lombok插件
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>
2. Employee 实体类
package com.groupies.jdk8.day03.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction 员工类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private Integer id;
private String name;
private Integer age;
private Double salary;
}
3. OptionalService 服务类,提供初始化数据方法
package com.groupies.jdk8.day03.service;
import com.groupies.jdk8.day03.po.Employee;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
public class OptionalService {
/**
* @return 初始化数据
*/
public static List<Optional<Employee>> getEmployee() {
//员工列表
Employee employee3 = new Employee(null, "张三", 20, 6666.66D);
Employee employee4 = new Employee(4, "赵四", 26, 3000D);
Employee employee5 = new Employee(5, "王五", 55, 6000D);
ArrayList<Optional<Employee>> list = new ArrayList<>();
list.add(Optional.of(employee3));
list.add(Optional.of(employee4));
list.add(Optional.of(employee5));
return list;
}
}
1 概述
Optional<T> 类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
常用方法:
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 1 | Optional.of | 创建 Optional 类
静态方法,创建一个 Optional 实例 | T value |Optional<T>
| 2 | Optional.empty | 创建 Optional 类
静态方法,创建一个 Optional 空实例 | - |Optional<T>
| 3 | Optional.ofNullable | 创建 Optional 类
静态方法
1. 入参 T 为null, 创建 Optional 空实例
2. 入参 T 不为null,创建 Optional 实例 | T| Optional<T>
| 4 | get | 获取对象
对于 Optional<T> 对象,通过get方法可以得到 T
其中 T 不能为空,否则会抛出异常 java.util.NoSuchElementException | - | T
| 5 | isPresent | 是否为空
1. 调用对象为null, 返回 false
2. 调用对象不为null,返回 true | - | boolean
| 6 | ifPresent | 安全消费值
1. 调用对象为null, 什么都不做
2. 调用对象不为null,通过Consumer接口(消费型接口)对其进行消费 | Consumer<? extends T> | void
| 7 | orElse | 获取对象/指定值
1. 调用对象为null, 返回 T
2. 调用对象不为null,返回 调用对象
注意: 无论optional是否有值,orElse都会被执行| T| T 或
Object
| 8 | orElseGet | 获取对象/指定值
1. 调用对象为null, 返回 Supplier提供的返回值
2. 调用对象不为null,返回 调用对象
注意: 只有optional为空时,orElseGet才会被执行| Supplier<? extends T> | T 或
Supplier提供的返回值
| 9 | orElseThrow | 获取对象/指定值
1. 调用对象为null, 抛出 X 异常
2. 调用对象不为null,返回 调用对象
注意: 只有optional为空时,orElseThrow才会被执行| Supplier<? extends X> throws X|<X extends Throwable> T
| 10 | filter | 过滤
1. Predicate结果为true, 返回调用对象
2. Predicate结果为false,返回Optional.empty()| Predicate<? super T>|Optional<T> 或
Optional.empty();
| 11 | map | 转换
1. 调用对象为null, 返回 Optional.empty()
2. 调用对象不为null,通过Function接口(函数型接口)对其进行处理,返回 Optional<任意值> | Function<? super T, ? extends U> |Optional<U> 或
Optional.empty();
| 12 | flatMap | 转换
1. 调用对象为null, 返回 Optional.empty()
2. 调用对象不为null,通过Function接口(函数型接口)对其进行处理,返回 Optional<任意值> | Function<? super T, Optional<U>> |Optional<U>
map与flatMap的区别:
1. 请求参数:
map: Function接口返回 任意类型 参数。
flatMap:Function接口返回 Optional类型 参数。
2. 返回值:
map: Function接口返回的参数,再 额外包装一层Optional。
flatMap:Function接口返回参数。
3. 结论: 简单理解,返回值类型为Optional<T>时使用flatMap,返回值为其他类型时使用map。
2 常用方法
案例1 Optional.of 创建实例
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 1 | Optional.of | 创建 Optional 类
静态方法,创建一个 Optional 实例 | T value |Optional<T>
案例代码一 Optional.of 创建实例
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.of
*/
public class Demo1OptionalOf {
public static void main(String[] args) {
Optional<Employee> opt = Optional.of(new Employee());
}
}
案例2 Optional.empty 创建空实例
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 2 | Optional.empty | 创建 Optional 类
静态方法,创建一个 Optional 空实例 | - |Optional<T>
案例代码二 Optional.empty 创建空实例
package com.groupies.jdk8.day03.practice;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.empty
*/
public class Demo2OptionalEmpty {
public static void main(String[] args) {
Optional<Object> opt = Optional.empty();
}
}
案例3 Optional.ofNullable 有则创建/无则empty()
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 3 | Optional.ofNullable | 创建 Optional 类
静态方法
1. 入参 T 为null, 创建 Optional 空实例
2. 入参 T 不为null,创建 Optional 实例 | T| Optional<T>
案例代码三 Optional.ofNullable 有则创建/无则empty()
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.ofNullable
*/
public class Demo3OptionalOfNullable {
public static void main(String[] args) {
//1. 入参 T 为null, 创建 Optional 空实例
Employee emp1 = null;
Optional<Object> opt1 = Optional.ofNullable(emp1);
System.out.println(opt1);//Optional.empty
//2. 入参 T 不为null,创建 Optional 实例
Employee emp2 = new Employee();
Optional<Object> opt2 = Optional.ofNullable(emp2);
System.out.println(opt2);//Optional[Employee(id=null, name=null, age=null, salary=null)]
}
}
案例4 get 获取对象
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 4 | get | 获取对象
对于 Optional<T> 对象,通过get方法可以得到 T
其中 T 不能为空,否则会抛出异常 java.util.NoSuchElementException | - | T
案例代码四 Optional.get 获取对象
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.get
*/
public class Demo4OptionalGet {
public static void main(String[] args) {
//对于 Optional<T> 对象,通过get方法可以得到 T
Employee emp1 = new Employee();
Optional<Object> opt1 = Optional.ofNullable(emp1);
System.out.println(opt1.get());//Employee(id=null, name=null, age=null, salary=null)
//其中 T 不能为空,否则会抛出异常 java.util.NoSuchElementException
Employee emp2 = null;
Optional<Object> opt2 = Optional.ofNullable(emp2);
System.out.println(opt2.get());//Exception in thread "main" java.util.NoSuchElementException: No value present
}
}
案例5 isPresent 是否为空
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 5 | isPresent | 是否为空
1. 调用对象为null, 返回 false
2. 调用对象不为null,返回 true | - | boolean
案例代码五 Optional.isPresent 是否为空
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.isPresent
*/
public class Demo5OptionalIsPresent {
public static void main(String[] args) {
//1. 调用对象为null,返回 false
Optional<Object> opt1 = Optional.empty();
System.out.println(opt1.isPresent());//false
//2. 调用对象不为null,返回 true
Optional<Object> opt2 = Optional.ofNullable(new Employee());
System.out.println(opt2.isPresent());//true
}
}
案例6 ifPresent 有则Consumer/无则跳过
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 6 | ifPresent | 安全消费值
1. 调用对象为null, 什么都不做
2. 调用对象不为null,通过Consumer接口(消费型接口)对其进行消费 | Consumer<? extends T> | void
案例代码六 Optional.ifPresent 有则Consumer/无则跳过
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.ifPresent
*/
public class Demo6OptionalIfPresent {
public static void main(String[] args) {
//1. 调用对象为null,什么都不做
Optional<Object> opt1 = Optional.empty();
opt1.ifPresent(o -> System.out.println(o + " 来消费了"));//
//2. 调用对象不为null,通过Consumer接口(消费型接口)对其进行消费
Optional<Object> opt2 = Optional.ofNullable(new Employee());
//Employee(id=null, name=null, age=null, salary=null) 来消费了
opt2.ifPresent(o -> System.out.println(o + " 来消费了"));
}
}
案例7 orElse 有则获取/无则Object
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 7 | orElse | 获取对象/指定值
1. 调用对象为null, 返回 T
2. 调用对象不为null,返回 调用对象
注意: 无论optional是否有值,orElse都会被执行| T| T 或
Object
案例代码七 Optional.orElse 有则获取/无则Object
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.orElse
*/
public class Demo7OptionalOrElse {
public static void main(String[] args) {
//1. 调用对象为null,返回 T
Optional<Object> opt1 = Optional.empty();
Object o1 = opt1.orElse(function());
System.out.println(o1);//function方法执行了:0
//2. 调用对象不为null,返回 调用对象
Optional<Object> opt2 = Optional.of(new Employee());
Object o2 = opt2.orElse(function());
System.out.println(o2);//function方法执行了:Employee(id=null, name=null, age=null, salary=null)
//3. orElse也可以直接传入Object类型参数
Object o = opt2.orElse(0);
}
//注意: 无论optional是否有值,orElse都会被执行
public static Object function() {
System.out.print("function方法执行了:");
return 0;
}
}
案例8 orElseGet 有则获取/无则Supplier
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 8 | orElseGet | 获取对象/指定值
1. 调用对象为null, 返回 Supplier提供的返回值
2. 调用对象不为null,返回 调用对象
注意: 只有optional为空时,orElseGet才会被执行| Supplier<? extends T> | T 或
Supplier提供的返回值
案例代码八 Optional.orElseGet 有则获取/无则Supplier
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.orElseGet
*/
public class Demo8OptionalOrElseGet {
final private static Employee admin = new Employee(0, "Administrator", 0, 0d);
public static void main(String[] args) {
//1. 调用对象为null,返回 T
Optional<Object> opt1 = Optional.empty();
System.out.println(opt1.orElseGet(() -> {
System.out.print("Optional对象为空===");
return admin;
}));//Optional对象为空===Employee(id=0, name=Administrator, age=0, salary=0.0)
//2. 调用对象不为null,返回 调用对象
Optional<Object> opt2 = Optional.of(new Employee());
System.out.println(opt2.orElseGet(() -> {
System.out.println("Optional对象为空");
return admin;
}));//Employee(id=null, name=null, age=null, salary=null)
}
}
案例9 orElseThrow 有则获取/无则异常
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 9 | orElseThrow | 获取对象/指定值
1. 调用对象为null, 抛出 X 异常
2. 调用对象不为null,返回 调用对象
注意: 只有optional为空时,orElseThrow才会被执行| Supplier<? extends X> throws X|<X extends Throwable> T
案例代码九 Optional.orElseThrow 有则获取/无则异常
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import java.util.Optional;
import java.util.function.Supplier;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.orElseThrow
*/
public class Demo9OptionalOrElseThrow {
public static void main(String[] args) throws Throwable {
//2. 调用对象不为null,返回 调用对象
Optional<Object> opt2 = Optional.of(new Employee());
System.out.println(opt2.orElseThrow((Supplier<Throwable>) () -> {
System.out.print("orElseThrow方法执行了:");
return new RuntimeException("Optional对象不能为空");
}));//Employee(id=null, name=null, age=null, salary=null)
//1. 调用对象为null,返回 T
Optional<Object> opt1 = Optional.empty();
System.out.println(opt1.orElseThrow((Supplier<Throwable>) () -> {
System.out.print("orElseThrow方法执行了:");
return new RuntimeException("Optional对象不能为空");
}));//orElseThrow方法执行了:Exception in thread "main" java.lang.RuntimeException: Optional对象不能为空
}
}
案例10 filter 过滤
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 10 | filter | 过滤
1. Predicate结果为true, 返回调用对象
2. Predicate结果为false,返回Optional.empty()| Predicate<? super T>|Optional<T> 或
Optional.empty();
需求: 过滤 id不为null 的员工,并打印
处理前:
Optional[Employee(id=null, name=张三, age=20, salary=6666.66)]
Optional[Employee(id=4, name=赵四, age=26, salary=3000.0)]
Optional[Employee(id=5, name=王五, age=55, salary=6000.0)]
处理后:
Optional.empty
Optional[Employee(id=4, name=赵四, age=26, salary=3000.0)]
Optional[Employee(id=5, name=王五, age=55, salary=6000.0)]
案例代码十 filter 过滤
package com.groupies.jdk8.day03.practice;
import com.groupies.jdk8.day03.po.Employee;
import com.groupies.jdk8.day03.service.OptionalService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction
*/
public class Demo10OptionalFilter {
@Autowired
private static OptionalService optionalService;
public static void main(String[] args) {
List<Optional<Employee>> list = optionalService.getEmployee();
System.out.println("=====处理前=====");
list.forEach(System.out::println);
List<Optional<Employee>> collect = list.stream()
//如果Optional<Employee>中Employee的id为空,则返回Optional.empty
.map(optional -> optional.filter(employee -> employee.getId() != null))
.collect(Collectors.toList());
System.out.println("=====处理后=====");
collect.forEach(System.out::println);
}
}
案例11 map 任意类型 转为 Optional
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 11 | map | 转换
1. 调用对象为null, 返回 Optional.empty()
2. 调用对象不为null,通过Function接口(函数型接口)对其进行处理,返回 Optional<任意值> | Function<? super T, ? extends U> |Optional<U> 或
Optional.empty();
案例代码十一 Optional.map 任意类型 转为 Optional
package com.groupies.jdk8.day03.practice;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.map
*/
public class Demo11OptionalMap {
public static void main(String[] args) {
Optional<Object> opt = Optional.of("abc");
Optional<Integer> res1 = opt.map((o) -> 5);
Optional<Optional<Integer>> res2 = opt.map((o) -> Optional.of(5));
System.out.println(res1);//Optional[5]
System.out.println(res2);//Optional[Optional[5]]
}
}
案例12 flatMap Optional 转为 Optional
|id| 方法名 | 方法作用 | 请求参数 |返回值类型 |
|:–|:–|:–|:–|:–|:–|
| 12 | flatMap | 转换
1. 调用对象为null, 返回 Optional.empty()
2. 调用对象不为null,通过Function接口(函数型接口)对其进行处理,返回 Optional<任意值> | Function<? super T, Optional<U>> |Optional<U>
案例代码十二 Optional.flatMap Optional 转为 Optional
package com.groupies.jdk8.day03.practice;
import java.util.Optional;
/**
* @author GroupiesM
* @date 2022/01/12
* @introduction Optional.filter
*/
public class Demo12OptionalFlatMap {
public static void main(String[] args) {
Optional<Object> opt = Optional.of("abc");
Optional<Integer> res = opt.flatMap((o) -> Optional.of(5));
System.out.println(res);//Optional[5]
}
}
22/01/14
M