一.简介
Optional 是一个对象容器,具有以下两个特点:
提示用户要注意该对象有可能为null
简化if else代码
二. 方法介绍
-
创建:
Optional.empty(): 创建一个空的 Optional 实例
Optional.of(T t):创建一个 Optional 实例,当 t为null时抛出异常
Optional.ofNullable(T t):创建一个 Optional 实例,但当 t为null时不会抛出异常,而是返回一个空的实例
-
获取:
get():获取optional实例中的对象,当optional 容器为空时报错
-
判断:
isPresent():判断optional是否为空,如果空则返回false,否则返回true
ifPresent(Consumer c):如果optional不为空,则将optional中的对象传给Comsumer函数
orElse(T other):如果optional不为空,则返回optional中的对象;如果为null,则返回 other 这个默认值
orElseGet(Supplier other):如果optional不为空,则返回optional中的对象;如果为null,则使用Supplier函数生成默认值other
orElseThrow(Supplier exception):如果optional不为空,则返回optional中的对象;如果为null,则抛出Supplier函数生成的异常
-
过滤:
filter(Predicate p):如果optional不为空,则执行断言函数p,如果p的结果为true,则返回原本的optional,否则返回空的optional
-
映射:
map(Function<T, U> mapper):如果optional不为空,则将optional中的对象 t 映射成另外一个对象 u,并将 u 存放到一个新的optional容器中。
flatMap(Function< T,Optional> mapper):跟上面一样,在optional不为空的情况下,将对象t映射成另外一个optional
区别:map会自动将u放到optional中,而flatMap则需要手动给u创建一个optional
三 .demo使用
package com.dume.boot.code;
import java.util.Optional;
/**
* @author dume
* @create 2021-09-13 10:53
*
* Optional是为了解决空指针异常,本质是一个包含可选值的包装类,或者说是一个容器
**/
public class OptionalDemo {
public static void main(String[] args) {
Student studentnull = null;
Student student = new Student("john1",11);
Student student2 = new Student("john2",22);
Student student3 = new Student("john3",33);
Student student4 = new Student("john4",44);
//isPresent判断值不为空,get返回对象
System.out.println("*******************isPresent判断值不为空,get返回对象**********************");
Optional<Student> optional = Optional.ofNullable(student);
if(optional.isPresent()){
Student back1 = optional.get();
System.out.println("back1:"+back1.toString());
}
System.out.println("*********************ifPresent判断不为空, 并执行Lambda 表达式********************");
//ifPresent判断不为空,Consumer(消费者) 参数,如果对象不是空的,就执行传入的 Lambda 表达式
//注意没有返回值
optional.ifPresent(u->ifFuction(u));
System.out.println("*********************orElse判断不为空,否则返回默认值********************");
//orElse判断不为空,否则返回默认值
Student back2 = Optional.ofNullable(studentnull).orElse(student2);
System.out.println("back2:"+back2.toString());
System.out.println("*******************orElseGet不为空时返回值;为空时作为参数传入函数式接口,并返回执行后的参数**********************");
//orElseGet不为空时返回值;为空时,他会作为参数传入Supplier(供应者) 函数式接口,并返回执行后的参数
Student back3 = Optional.ofNullable(studentnull).orElse(createStudent());
Student back4 = Optional.ofNullable(studentnull).orElseGet(()->createStudent());
System.out.println("back3:"+back3.toString());
System.out.println("back4:"+back4.toString());
/**
* 可见当都为空时,orElse与orElseGet并无差别
* 当都不为空时,orElse依然会执行,orElseGet不会执行。所以orElseGet效率更高
*/
System.out.println("*********************当都不为空时,orElse依然会执行,orElseGet不会执行********************");
Student back5 = Optional.ofNullable(student).orElse(createStudent());
Student back6 = Optional.ofNullable(student).orElseGet(()->createStudent());
System.out.println("back5:"+back5.toString());
System.out.println("back6:"+back6.toString());
//orElseThrow当为空时,抛出自定义异常
System.out.println("*********************orElseThrow当为空时,抛出自定义异常********************");
try {
Student back7 = Optional.ofNullable(studentnull).orElseThrow(()-> new IllegalArgumentException());
}catch (Exception e){
e.printStackTrace();
}
//map转换值,map() 对值调用作为参数的函数,然后将返回的值包装在 Optional
System.out.println("*********************map转换值********************");
String back8 = Optional.ofNullable(studentnull).map(u->u.getName()).orElse("DEFUAFT");
String back9 = Optional.ofNullable(studentnull).map(Student::getName).orElse("DEFUAFT");
System.out.println("back8:"+back8);
System.out.println("back9:"+back9);
//flatMap() 也需要函数作为参数,并对值调用这个函数,然后直接返回结果;其实就是需要传入Optional类型参数,并返回Optional类型
System.out.println("********************flatMap()转换值 需要传入Optional类型*********************");
student.setPosition("Position");
String position = Optional.ofNullable(student)
.flatMap(u -> u.getPosition()).orElse("defaultPosition");
System.out.println("back10:"+position);
//filter() 接受一个 Predicate 参数,返回测试结果为 true 的值。
// 如果测试结果为 false,会返回一个空的 Optional。
System.out.println("*******************filter() 接受判断表达式,返回判断结果**********************");
Optional<Student> optional11 = Optional.ofNullable(student).filter(u->u.getName()!=null&&u.getName().contains("1"));
System.out.println("back11:"+optional11.isPresent());
//使用Optional避免空指针来取值
System.out.println("*******************使用Optional避免空指针来取值**********************");
String code = Optional.ofNullable(new User())
.flatMap(User::getAddress)
.flatMap(Address::getCountry)
.map(Country::getCode)
.orElse("defaultcode");
System.out.println("back12:"+code);
System.out.println("*****************************************");
}
public static Student createStudent(){
System.out.println("CreateStudent loading......");
return new Student("Createjohn",0);
}
public static void ifFuction(Student student){
System.out.println("ifFuction loading......");
}
static class Student{
public String name;
public int age;
public String position;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", position=" + position +
'}';
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void setPosition(String position) {
this.position = position;
}
public Optional<String> getPosition() {
return Optional.ofNullable(position);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
static class User{
Address address;
public Optional<Address> getAddress() {
return Optional.ofNullable(address);
}
}
static class Address{
Country country;
public Optional<Country> getCountry() {
return Optional.ofNullable(country);
}
}
static class Country{
String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
}
*******************isPresent判断值不为空,get返回对象**********************
back1:Student{name='john1', age=11, position=null}
*********************ifPresent判断不为空, 并执行Lambda 表达式********************
ifFuction loading......
*********************orElse判断不为空,否则返回默认值********************
back2:Student{name='john2', age=22, position=null}
*******************orElseGet不为空时返回值;为空时作为参数传入函数式接口,并返回执行后的参数**********************
CreateStudent loading......
CreateStudent loading......
back3:Student{name='Createjohn', age=0, position=null}
back4:Student{name='Createjohn', age=0, position=null}
*********************当都不为空时,orElse依然会执行,orElseGet不会执行********************
CreateStudent loading......
back5:Student{name='john1', age=11, position=null}
back6:Student{name='john1', age=11, position=null}
*********************orElseThrow当为空时,抛出自定义异常********************
java.lang.IllegalArgumentException
at com.dume.boot.code.OptionalDemo.lambda$main$3(OptionalDemo.java:58)
at java.util.Optional.orElseThrow(Optional.java:290)
at com.dume.boot.code.OptionalDemo.main(OptionalDemo.java:58)
*********************map转换值********************
back8:DEFUAFT
back9:DEFUAFT
********************flatMap()转换值 需要传入Optional类型*********************
back10:Position
*******************filter() 接受判断表达式,返回判断结果**********************
back11:true
*******************使用Optional避免空指针来取值**********************
back12:defaultcode
*****************************************
Disconnected from the target VM, address: '127.0.0.1:60721', transport: 'socket'
Process finished with exit code 0