Optional<T>类是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在Optional可以更好地表达这个概念。并且可以避免空指针异常。
-
Optional.of(T t):创建一个Optional实例。对于该方法,传入的参数一定不能为
null
,否则便会抛出NullPointerException
。
private final T value;
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
- Optional.empty():创建一个空的Optional实例。即该 Optional 中不包含值。
private static final Optional<?> EMPTY = new Optional<>();
private Optional() {
this.value = null;
}
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
-
Optional.ofNullable(T t):若 t 不为null,创建Optional实例,否则创建空实例。该方法和 of 方法的区别在于,传入的参数可以为
null
。因为该方法会判断传入的参数是否为 null,如果为 null 的话,返回的就是 Optional.empty()。
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
- get():获取 Optional 包含的值,如果值不存在,如在一个Optional.empty 上调用 get() 方法的话,将会抛出 NoSuchElementException 异常。
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
- isPresent():判断是否包含值。
- orElse(T t):如果调用对象包含值,返回该值,否则返回 t 。
- orElseGet(Supplier s):当 Optional 中有值的时候,返回值;当 Optional 中没有值的时候,返回从该 Supplier 获得的值。
- map(Function mapper):如果有值对其处理,然后将返回的值包装在 Optional 中返回,否则返回Optional.empty()。
-
flatMap(Function mapper):与map类似,区别在于,map 方法参数中的函数 mapper 输出的是值,然后 map 方法会使用
Optional.ofNullable
将其包装为 Optional;而 flatMap 要求参数中的函数 mapper 输出的就是 Optional。 - filter(Predicate p):filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.empty。
【代码示例】
public class TestOptional {
@Test
public void test1(){
Optional<Employee> op = Optional.of(new Employee());
Employee e = op.get();
System.out.print(e);
}
@Test
public void test2(){
// 第一行(也就是op.get()之前)就会会产生NullPointException异常,能快速锁定传入的就是空值
Optional<Employee> op = Optional.of(null);
System.out.print(op.get());
// 构建一个空的Optional,不会产生异常
Optional<Employee> op1 = Optional.empty();
System.out.print(op1.get());
Optional<Employee> op2 = Optional.ofNullable(new Employee());
System.out.print(op2.get());
// op3.get() 会产生NullPointException异常
Optional<Employee> op3 = Optional.ofNullable(null);
System.out.print(op3.get());
}
@Test
public void test3(){
Optional<Employee> op = Optional.ofNullable(null);
// 判断是否包含值,如果包含则打印
/*if(op.isPresent()){
System.out.print(op.get());
}*/
// 如果op.get()是空那么就返回默认值,这样就不会产生空指针异常
Employee emp = op.orElse(new Employee("张三",18,888.9, Employee.Status.FREE));
System.out.print(emp);
}
@Test
public void test4(){
Optional<Employee> op = Optional.ofNullable(null);
// 函数式接口,可以写任何你想要的功能,而不仅仅是new Employee()
Employee emp = op.orElseGet(()->new Employee());
System.out.print(emp);
}
@Test
public void test5(){
Optional<Employee> op = Optional.ofNullable(new Employee("张三",18,888.9, Employee.Status.FREE));
Optional<String> str = op.map((e)->e.getName());
System.out.print(str.get()); //输出“张三”
}
@Test
public void test6(){
Optional<Employee> op = Optional.ofNullable(new Employee("张三",18,888.9, Employee.Status.FREE));
// flapMap要求返回值为 Optional<U>,进一步避免空指针的影响
Optional<String> str = op.flatMap((e) -> Optional.of(e.getName()));
System.out.print(str.get()); //输出“张三”
}
}
Optional的好处
public class Godness {
// 女神一定有名字,这样的值就可以不用封装到Optional中
private String name;
public Godness(String name) {
this.name = name;
}
public Godness() { }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Man {
private Godness godness;
public Man() { }
public Man(Godness godness) {
this.godness = godness;
}
public Godness getGodness() {
return godness;
}
public void setGodness(Godness godness) {
this.godness = godness;
}
}
public class NewMan {
/**
* 每个男人心中有可能有女神,有可能没有。Optional<>就是封装有可能有有可能没有的值
*
* 如果不给Optional对象赋值,那么默认这个Optional对象就是null,就没有意义了,
* 所以给Optional对象赋值为Optional.empty(),也就是一个空的Optional对象,而不是null
*/
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;
}
}
public class TestMan {
@Test
public void test1(){
//产生空指针异常,这个男人没有女神
Man man = new Man();
String name = getGodnessName(man);
System.out.print(name);
Optional<NewMan> op = Optional.ofNullable(null);
String str = getGodnessName2(op); //不能直接传null,会产生NullPointException
System.out.print(str);
}
// 需求:获取一个男人心中女神的名字
public String getGodnessName(Man man){
if(man!=null){
Godness gn = man.getGodness();
if(gn!=null){
return gn.getName();
}
}
return "石原里美";
}
//传入参数也可能是空值,所以我们也可以用Optional进行封装
public String getGodnessName2(Optional<NewMan> man){
return man.orElse(new NewMan()) // 输入参数为空则new 一个男人
.getGodness()
.orElse(new Godness("石原里美")) //没有女神就返回一个默认的女神
.getName();
}
}