Optional
为什么要有这个?
先来看个例子,思考一下会输出null还是报错呢?
public class TestOptional {
public static void main(String[] args) {
OptionTest optionTest = new OptionTest();
System.out.println(optionTest.getInnerParam().getInnerInnerParam().getParam());
}
}
@Data
class OptionTest{
private int id;
private int age;
private InnerParam innerParam;
}
@Data
class InnerParam{
private int param;
private InnerInnerParam innerInnerParam;
}
@Data
class InnerInnerParam{
private int param;
private int superman;
}
输出:
Exception in thread "main" java.lang.NullPointerException
at com.example.demostudy.kusch.javabase.optional.TestOptional.main(TestOptional.java:18)
Process finished with exit code 1
很明显报错了。
解决这个报错很简单,加判断呗。
public class TestOptional {
public static void main(String[] args) {
OptionTest optionTest = new OptionTest();
InnerParam innerParam = optionTest.getInnerParam();
if (null!=innerParam){
InnerInnerParam innerInnerParam = innerParam.getInnerInnerParam();
if (null!=innerInnerParam){
System.out.println(innerInnerParam.getParam());
}
}
}
}
@Data
class OptionTest{
private int id;
private int age;
private InnerParam innerParam;
}
@Data
class InnerParam{
private int param;
private InnerInnerParam innerInnerParam;
}
@Data
class InnerInnerParam{
private int param;
private int superman;
}
这虽然可以很好的解决,但是如果嵌套层数很深,那你是不是打算写一整页的if
判断??
Optional的使用
先看使用
public class TestOptional {
public static void main(String[] args) {
OptionTest optionTest = new OptionTest();
Integer result = Optional.ofNullable(optionTest)
.map(OptionTest::getInnerParam)
.map(InnerParam::getInnerInnerParam)
.map(InnerInnerParam::getSuperman)
.orElse(999);
System.out.println(result);
}
}
@Data
class OptionTest {
private int id;
private int age;
private InnerParam innerParam;
}
@Data
class InnerParam {
private int param;
private InnerInnerParam innerInnerParam;
}
@Data
class InnerInnerParam {
private int param;
private int superman;
}
输出:
999
Process finished with exit code 0
可以看出这样不仅可以处理处理空指针异常,还可以处理,在没有值的时候所需要返回的结果。
Optional补充
public class OptionalDemo {
public static void main(String[] args) {
House house = new House();
Television tv = new Television();
tv.setCartoon("cat");
house.setTelevision(tv);
Boolean cartoonFlag = true;
String cartoon = Optional.ofNullable(house)
//类中改写Optional包装
.flatMap(House::getTelevision)
//没改写Optional包装
.map(Television::getCartoon)
//过滤,上述条件都过了,到这判断不能包含cat
.filter((a) -> !tv.getCartoon().contains("cat"))
//所有不符合之后要做的事
.orElseGet(() -> {
if (cartoonFlag) {
return "niubi";
}
return "hahaha";
});
System.out.println(cartoon);
}
}
class House {
private Television television;
public void setTelevision(Television television) {
this.television = television;
}
public Optional<Television> getTelevision() {
return Optional.ofNullable(television);
}
}
class Television {
private String cartoon;
public String getCartoon() {
return cartoon;
}
public void setCartoon(String cartoon) {
this.cartoon = cartoon;
}
}
注意House
类中的getTelevision()
方法,直接在实体类中包装optional
返回,配合flatMap
使用,其实区别不大。
最后附上map
、flatMap
、orElseGet
的方法注释图。