🍰 个人主页:不摆烂的小劉
🍞文章有不合理的地方请各位大佬指正。
🍉文章不定期持续更新,如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️
文章目录
一、什么是Optional?
在 Java 8 中,Optional
是一个新的容器类,它被引入以更好地处理可能为 null
的值。
Optional
的主要目的是提供一种优雅的方式来避免空指针异常(NullPointerException)
二、Optional常用api
1.Optional.empty()
创建一个空的Optional对象
Optional<Car> optCar = Optional.empty();
2.Optional.of()
- 静态工厂方法,依据非空值创建对象
- 如果
car
是一个null
,这段代码会立即抛出一个NullPointerException
Optional<Car> optCar = Optional.of(car);
3.Optional.ofNullable
- 创建一个允许
null
值的Optional
对象 - 如果
car
是null
,那么得到的Optional
对象就是个空对象。
Optional<Car> optCar = Optional.ofNullable(car);
4.map
Optional
是一个容器类,用于封装可能为 null 的值。- 不是一个传统的容器,如 List、Set、Map,只能存储一个值或者不存储任何值(即为空)
Optional
对象包含一个非空值,那么map
方法会根据提供的函数,返回一个新的Optional
对象,该对象包含转换后的值。- 如果原始
Optional
对象为空,则返回一个空的Optional对象
。
// 保险
@Data
public class Insurance {
private String name;
public String getName() {
return name;
}
}
@Test
public void test1() {
Insurance insurance = new Insurance();
insurance.setName("阳光保险");
Optional<String> name = Optional.ofNullable(insurance).map(Insurance::getName);
System.out.println(name);//阳光保险
}
@Test
public void test2() {
Insurance insurance = new Insurance();
Optional<String> name = Optional.ofNullable(insurance).map(Insurance::getName);
System.out.println(name);//Optional.empty
}
5.flatMap
flatMap
操作中使用 处理嵌套的 Optional
类型。
// 保险
@Data
public class Insurance {
private String name;
public String getName() {
return name;
}
}
@Test
public void test3() {
Optional<Insurance> optInsurance = Optional.ofNullable(new Insurance());
Optional<String> name = optInsurance
.flatMap(insurance -> {
System.out.println("insurance");//insurance
return Optional.ofNullable(insurance.getName());
});
System.out.println(name);
/*
结果:
insurance
Optional.empty
*/
}
6.ifPresent
- 存在就执行使用该值的方法调用
@Test
public void test4() {
Optional<Insurance> optInsurance = Optional.ofNullable(new Insurance());
optInsurance.ifPresent(insurance -> System.out.println(insurance));
}
7.get
- 如果变量存在,它直接返回封装的变量值
- 否则就抛出一个
NoSuchElementException
异常 - 一般不用单独使用,除非确定值存在,不然失去了Optional的意义
@Test
public void test4() {
Insurance insurance = new Insurance();
insurance.setName("保险");
Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
System.out.println(optInsurance.get().getName());//保险
}
8.orElse
在 Optional对象不包含值时提供一个默认值。
public String str() {
//模拟取值
return null;
}
/**
* orElse
*/
@Test
public void test5() {
String s = Optional.ofNullable(str()).orElse("default");
System.out.println(s);//default
}
9.orElseGet
public String str() {
//模拟取值
return null;
}
/***
* orElseGet
*/
@Test
public void test6() {
Supplier<String> supplier = () -> {
return "default";
};
String s = Optional.ofNullable(str()).orElseGet(supplier);
System.out.println(s); // default
}
10.orElseThrow
指定Supplier
抛出的异常
public String strData() {
return null;
}
/**
* orElseThrow
*/
@Test
public void test7() {
try {
Optional.ofNullable(strData()).orElseThrow(RuntimeException::new);
} catch (RuntimeException e) {
System.out.println("RuntimeException");
}
//结果RuntimeException
}
11.filter`
是否满足谓词,满足返回包含该值的Optional
对选,否则返回Optional.empty
@Test
public void test8() {
Insurance insurance = new Insurance();
insurance.setName("A保险");
Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
optInsurance
.filter((Insurance i) -> "A保险".equals(i.getName()))
.ifPresent(System.out::println);
}
三、其他问题:
1. Optional为何不可在 类中使用?
- 由于
Optional
类设计时未实现 Serializable接口
,无法序列化
反例:
public class Person {
private Optional<Car> car;
public Optional<Car> getCar() { return car; }
}
2.为何避免使用 基础类型的Optional对象?
- 除了Optional还提供
OptionalInt、OptionalLong、OptionalDouble
基础类型对象虽然提高了一些性能,但是灵活性大大较低 基础类型Optional
不支持map flatMap filter
中间操作
参考:《java8 实战》
🍉文章不定期持续更新,如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️