Java1.8 Optional简单使用

        听到同事们说Optional类是Java1.8新增的类可以用来判断对象是否为null。当时感到一丝丝疑问:为了判null至于新出一个类吗?直到了学习了官方文档和实际演示了一遍,发现Optional并不是只是判null这么简单。

     Java1.8发布了十来年,实际也使用了四五年,今天才开始正式学习新增的特新之一。实在汗颜。废话不多说了,来看看Optional类是如何处理对象为空的情况。

一、简单应用

来看下常规是的示例:

        List<String> list = null;
        if(null != list){
            list.forEach((String a )->System.out.println(a));
        }

通常情况下,当接收的对象可能存在null时,我们可能会增加一层判空条件来避免万恶的空指针。

而Optional给我们又提供了一种的新的处理方式:通过增加一个默认的返回对象,来避免空指针。

 List<String> list = null;
 Optional.ofNullable(list).orElse(Arrays.asList("1","2","3")).forEach((String a )->System.out.println(a));

通过调用Optional类的ofNullable和orElse方法就规避了空指针的情况。

那Optional类是如何解决的这种情况,看下Optional的源码:

 /**
     * Returns an {@code Optional} describing the specified value, if non-null,
     * otherwise returns an empty {@code Optional}.
     *
     * @param <T> the class of the value
     * @param value the possibly-null value to describe
     * @return an {@code Optional} with a present value if the specified value
     * is non-null, otherwise an empty {@code Optional}
     */
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

   /**
     * Returns an empty {@code Optional} instance.  No value is present for this
     * Optional.
     *
     * @apiNote Though it may be tempting to do so, avoid testing if an object
     * is empty by comparing with {@code ==} against instances returned by
     * {@code Option.empty()}. There is no guarantee that it is a singleton.
     * Instead, use {@link #isPresent()}.
     *
     * @param <T> Type of the non-existent value
     * @return an empty {@code Optional}
     */
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

 /**
     * Return the value if present, otherwise return {@code other}.
     *
     * @param other the value to be returned if there is no value present, may
     * be null
     * @return the value, if present, otherwise {@code other}
     */
    public T orElse(T other) {
        return value != null ? value : other;
    }

从源码中看出ofNullable(T value)方式的Optional提供的静态方法,当value不为null将返回指定value类型的Optional对象,如果为空则返回一个没有指定类型的Optional对。

orElse(T other)是Optional提供的成员方法,意在提供另一种选择,当other不为null则直接返回other,如果传入的是null,则返回的也是null。

以上是关于对Optional的初探。而当注意到源码的方法不止两个时,可能也会对这个类其他方法有兴趣去一探究竟。

二、简单分析Optional类的API

先看下具体的都有哪些方法

(1)类的属性:从Optional类并不复杂,类本身被final修饰不能被继承,同时构造方法私有化,通过new的方式肯定是实现不了。但是Optional类提供了三个可创建Optional对象的静态方法。

ofNullable(T value)

of(T value)

两个方法类似,但是最大的区别是当入参为null时of依然会报空指针异常,而ofNullable会返回一个没有指定类型的Optional对象,empty()方法显而易见只是创建了一个没有指定类型的Optional对象。在开发过程中ofNullable应该会是首选。

public final class Optional<T> {    
    //构造方法   
    private Optional() {
        this.value = null;
    }
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
    //静态方法
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
    
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
    
    

 (2)成员方法:

isPresent();

get();

ifPresent(Consumer<? super T> consumer);

isPresent()和get()这个两个成员方法是关于值的判断:isPresent判断Optional是否已经被实例化,如果不为null可以配合get()方法获取指定类型;ifPresen可以通过函数Consumer对指定类型对象进程处理。

  //源码1
  public boolean isPresent() {
        return value != null;
  }
  public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
       return value;
  }
 //源码2
  public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
  }
  //示例1
    Optional<List<String>> optionalStringList = Optional.ofNullable(new ArrayList<>());
    if(optionalStringList.isPresent()){
        List<String> list = optionalStringList.get(); 
    }
  }

  //示例2
  Optional<List<String>> optionalStringList =         
  Optional.ofNullable(Arrays.asList("1","2","3"));
        optionalStringList.ifPresent( list -> list.forEach((String a )->System.out.println(a)));

map(Function<? super T, ? extends U> mapper);

flatMap(Function<? super T, Optional<U>> mapper);

这两个实例方法依然可以通过函数对指定类型处理,两个方法区别是 map(Function<? super T, ? extends U> mapper)方法可以返回其他指定的类型的Optional,也就是你给了我什么,我不一定还给你什么。而flatMap(Function<? super T, Optional<U>> mapper)应为做了限定,所以也就是你给什么我就还给你什么。

//源码 
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, Optional<U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }
  //示例 
  List list = new ArrayList();
        list.add("1");
        Optional<List<String>> optionalStringList = Optional.ofNullable(list);
        Optional<List<String>> optionalStringList1 = optionalStringList.flatMap(list2 -> {
            list2.add("4");
            return optionalStringList;
        });
   List<String> strings1 = optionalStringList.get();
 
//示例
 Optional<List<String>> optionalStringList2 = Optional.ofNullable(Arrays.asList("1", "2", "3"));

        Optional<HashMap<String, String>> stringStringHashMap = optionalStringList2.map(list3 -> {
            HashMap<String, String> map = new HashMap<>();
            for (int i = 0; i < list3.size(); i++) {
                map.put(list3.get(i), String.valueOf(i));
            }
            return map;
        });
        HashMap<String, String> stringStringHashMap1 = stringStringHashMap.get();

 orElse(T other)当指定返回类型为空时,返回入参指定类型为orhter的Optional对象

orElseGet(Supplier<? extends T> other)  使用函数Supplier 返回指定类型的具体对象,如果指定类型为空,则返回other指定类型对象。

 orElseThrow(Supplier<? extends X> exceptionSupplier) 返回自定义异常

  //源码
  public T orElse(T other) {
        return value != null ? value : other;
    }

  //示例:
  List<String> strings = Optional.ofNullable(Arrays.asList("1")).orElse(new ArrayList<>());
 //源码
 public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
 }

//示例
 Optional<List<String>> optionalStringList2 = Optional.ofNullable(Arrays.asList("4","5","6"));
 Optional<List<String>> optionalStringList = Optional.ofNullable(Arrays.asList("1","2","3")).orElseGet(() -> {
            return  optionalStringList2.get()
  });
//源码
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws 
  {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }  

 //示例
 Optional.ofNullable(null).orElseThrow(() -> new Exception("值为空"));
     

 filter(Predicate<? super T> predicate) 使用函数Predicat的拦截器,如果存在一个值,并且该值与给定谓词匹配。

public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
}

//示例:
List<String > list = new ArrayList<>();
 list.add("1");
 List<String> newList = Optional.ofNullable(list).filter((x) -> x.add("3")).get();

三、总结:

    Optional类的方法虽然不多,但是麻雀虽小,五脏俱全。Optional本身是一个容器对象,它提供了对于非null值的操作方法,对于对象操作提供了更多的可能性,尤其配合函数式编程和Lambda表达式更能发挥其强大的作用,也可以说Optional是函数式编程和Lambda表达式的最佳实践之一。

 参考:Java SE8 API在线文档地址:Java Platform SE 8

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值