package com.example.demo.lambdaOptional;
import com.example.demo.lambda.Employee;
import org.junit.Test;
import java.util.Optional;
/**
* @Description
* Optional<T>
* (java.util.Optional)
*
* Optional 容器类:用于尽量避免空指针异常
* 1. 是一个容器类,代表一个值存在或不存在。
* 2. 原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。
* 3. 并且可以避免空指针异常。
*
* Optional.of(T t) : 创建一个 Optional 实例
* Optional.empty() : 创建一个空的 Optional 实例
* T get() : 如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
* Optional.ofNullable(T t): 若 t 不为 null,创建 Optional 实例,否则创建空实例
* isPresent() : 判断是否包含值
* orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
* orElseGet(Supplier s) : 如果调用对象包含值,返回该值,否则返回 s 获取的值
* map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
* flatMap(Function mapper): 与 map 类似,要求返回值必须是Optional
*
* @Auther gf.x
* @Date 2020/3/30 14:35
*/
public class OptionalTest {
//map(Function f) 方法
@Test
public void test5() {
//Optional<Employee> optional = Optional.ofNullable(new Employee("张三", 18, 9999.99, Employee.Status.FREE));
Optional<Employee> optional = Optional.of(new Employee("张三", 18, 9999.99, Employee.Status.FREE));
Optional<String> s = optional.map(Employee::getName);
System.out.println(s.get()); //在使用get()时,一般要使用isPresent()验证 防止发生异常
//相比与map,flatMap使用optional对值进行了封装 避免空指针异常
Optional<String> op3 = optional.flatMap((e) -> Optional.of(e.getName()));
System.out.println(op3.get());
}
//isPresent()、orElse(T t) 方法
//orElse(T t) : 如果optional包含值则返回,否则定义个默认值返回
@Test
public void test3() {
//Optional<Employee> optional = Optional.ofNullable(new Employee());
Optional<Employee> optional = Optional.ofNullable(null);
if (optional.isPresent()) {
System.out.println(optional.get());
}
}
@Test
public void test4() {
//Optional<Employee> optional = Optional.ofNullable(new Employee());
Optional<Employee> optional = Optional.ofNullable(null);
Employee employee = optional.orElse(new Employee("张三", 18, 9999.99, Employee.Status.FREE));
System.out.println(employee);
//orElseGet(Supplier s) 和 orElse(T t) 相比更灵活一些,orElseGet()方法里面是函数式接口
Employee employee1 = optional.orElseGet(Employee::new);
System.out.println(employee1);
}
//Optional.ofNullable(T t) 方法
@Test
public void test2() {
//Optional<Employee> optional = Optional.ofNullable(new Employee());
/*
Optional.ofNullable()的值可以为null,但get()时会报NoSuchElementException异常
通过查看Optional.ofNullable()方法源码:
return value == null ? empty() : of(value)
可知此方法是 of() 和 empty() 方法的综合。
*/
Optional<Employee> optional = Optional.ofNullable(null);
Employee employee = optional.get();
System.out.println(employee);
}
//Optional.empty() 方法
@Test
public void test1() {
Optional<Object> emptyOptional = Optional.empty();
//由于Optional是空的,所以在get()时会报NoSuchElementException异常
//但此时也不会报空指针异常
Object o = emptyOptional.get();
System.out.println(o);
}
//Optional.of(T t) 方法
@Test
public void test() {
Optional<Employee> optional = Optional.of(new Employee());
//Optional.of()的值不能是null,否则optional.get()时就会报空指针异常
//Optional<Employee> optional = Optional.of(null);
Employee employee = optional.get();
System.out.println(employee);
}
/**
* Optional 实战应用
* 需求:获取一个男人心中女神的名字
*/
@Test
public void test6() {
//Man man = new Man(new Godness("宋慧乔"));
Man man = new Man();
String godnessName = getGodnessName(man);
System.out.println(godnessName);
}
//不使用Optional容器类
/**
* 像下面这个方法,由于业务逻辑需要,必须要进行多层if/if else嵌套;
* 这样的话代码的可读性就降低了很多;
* 此时我们一般可以逻辑反过来写,先判断 == null 的时候,这样就避免了if else的多层嵌套问题
*/
public String getGodnessName(Man man) {
if (man != null) {
Godness god = man.getGod();
if (god != null) {
return god.getName();
}
}
return "林允儿";
}
//使用Optional的实体类
@Test
public void test7(){
//Optional<Godness> godness = Optional.ofNullable(new Godness("林允儿"));
//Optional<NewMan> op = Optional.ofNullable(new NewMan(godness));
Optional<NewMan> op = Optional.ofNullable(null);
String name = getGodnessName1(op);
System.out.println(name);
}
public String getGodnessName1(Optional<NewMan> newMan) {
return newMan.orElse(new NewMan())
.getGodness()
.orElse(new Godness("宋慧乔"))
.getName();
}
}
package com.example.demo.lambdaOptional;
public class Godness {
private String name;
public Godness() {
}
public Godness(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Godness [name=" + name + "]";
}
}
package com.example.demo.lambdaOptional;
public class Man {
private Godness god;
public Man() {
}
public Man(Godness god) {
this.god = god;
}
public Godness getGod() {
return god;
}
public void setGod(Godness god) {
this.god = god;
}
@Override
public String toString() {
return "Man [god=" + god + "]";
}
}
package com.example.demo.lambdaOptional;
import java.util.Optional;
public class NewMan {
/**
* Optional 的使用场景是:
* 当某个变量/对象的值可能是null,也可能不是null时;
* 这时我们就需要把它封装到Optional中,进而避免发生空指针异常。
*/
//不能这样写,这样写Optional<Godness> godness的值就是null
//private Optional<Godness> godness;
//把Godness包装/封装到Optional里面
private Optional<Godness> godness = Optional.empty();
public NewMan() {
}
public NewMan(Optional<Godness> godness) {
this.godness = godness;
}
public Optional<Godness> getGodness() {
return godness;
}
public void setGodness(Optional<Godness> godness) {
this.godness = godness;
}
@Override
public String toString() {
return "NewMan{" +
"godness=" + godness +
'}';
}
}