JDK OPTIONAL

  • Post author:
  • Post category:其他

章节 方法名 JDK版本 备注
创建Optional对象 of() 8 创建一个Optional
ofNullable() 8 上下两者的结合体,推荐使用
empty() 8 空的Optional
获取Optional对象 orElse 8 为不为空都会被调用
orElseGet 8 区别在于只有等到为空的时候才调用 (推荐)
orElseThrow 8 为空抛出异常
消费Optional的值 ifPresent 8 对象参数赋值
ifPresentOrElse 9
管道化Optional map 8 一一映射
filter 8 过滤器
flatMap 8

1. 创建Optional对象

方法名 JDK版本 备注
of() 8 创建一个Optional
ofNullable() 8 上下两者的结合体,推荐使用
empty() 8 空的Optional

注意:区别在于of()使用null创建直接报错,ofNullable()使用null等价于empty()

public class MyOptionalTest {
    @Test
    public void test05(){
        Optional<String> optionalS = Optional.of("Hello");
        Optional<String> optional = Optional.ofNullable("Hello");
        Optional<Object> empty = Optional.empty();
    }
}

2. 获取Optional对象

方法名 JDK版本 备注
orElse 8 为不为空都会被调用
orElseGet 8 区别在于只有等到为空的时候才调用 (推荐)
orElseThrow 8 为空抛出异常
public class MyOptionalTest {
    @Test
    public void test01(){
        Optional<String> str = Optional.of("Hello");
        String s = str.orElse("w");
        System.out.println(s);
        String s1 = str.orElseGet(() -> "");
        String s2 = str.orElseThrow(IllegalStateException::new);
    }
}

3. 消费Optional的值

可以用于对象的赋值操作

方法名 JDK版本 备注
ifPresent 8
ifPresentOrElse 9
public class MyOptionalTest {
    @Test
    public void test02(){
        Optional<String> str = Optional.of("Hello");
        str.ifPresent(System.out::println);
        str.ifPresentOrElse(System.out::println, ()->{employee.setName("")});
    }
}

4. 管道化Optional

方法名 JDK版本 备注
map 8 一一映射
filter 8 过滤器
flatMap 8

其中flatMap本质上和Map相同,源码上只是进行了一次Optional包裹

public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent()) {
        return empty();
    } else {
        return Optional.ofNullable(mapper.apply(value));
    }
}
public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent()) {
        return empty();
    } else {
        @SuppressWarnings("unchecked")
        Optional<U> r = (Optional<U>) mapper.apply(value);
        return Objects.requireNonNull(r);
    }
}

可以看出两者本质上是相同的,在这里不同于Stream中的map和flatMap

public class MyOptionalTest {
    @Test
    public void test03(){
        Optional<String> str = Optional.of("Hello");
        Optional<String> s = str.filter(s1 -> s1.length() > 1).map(String::toUpperCase);
        Optional<Integer> optional = Optional.of(-1);
        Optional<Double> optionalDouble = optional.flatMap(i -> i < 0 ? Optional.empty() : Optional.of(Math.sqrt(i)));
        Optional<Double> aDouble = optional.map(i -> i < 0 ? null : Math.sqrt(i));
    }
}

5. 不推荐的方式处理Optional

不合理的方式处理Optional

  1. Optional.of(null); 会出现报错
  2. 不推荐之间使用get方法获取参数
    Optional.empty() or Optional.ofNullable() 直接get() 会报错
    if(optional.isPresent) optional.get() 并不会变得简约
    JDK10将get方法称之为orElseThrow()

推荐使用的策略

1… Optional 永远不要为null Optional<User> user = null;

  1. 不要使用Optional的域 在类的内部使用null表示更加易于操作
  2. 不要在集合中放置Optional对象,更不要将Optional作为map其中的键,而是应该直接获得对应的值

版权声明:本文为qq_41503660原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。