zoukankan      html  css  js  c++  java
  • Optional的简单理解

    Optional的简单理解

    在上篇博客简单讲解了 Stream 的基本用法,Stream的许多终端操作返回类型为 Optional 类型,第一次见到这个类型,看了源码及网上的资料有了简单的理解。

    image-20201201161127285

    1、Optional 介绍

    Optional 是 JDK8 新增的一个类,看了下源码,可以知道 Optional 是一个用来存储对象的辅助类,可以判断对象是否为空并进行后续操作。

    image-20201201162644689

    2、Optional 创建

    除了 Stream 方面的应用,如果平常需要使用 Optional,有以下三种方法创建 Optional。

    2.1、Optional.empty()

    private static final Optional<?> EMPTY = new Optional<>();
    
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
    

    直接创建一个空的Optional。

    2.2、Optional.of()

    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    

    如果传进来的对象为 null , 则会抛出异常。

    2.3 Option.ofNullable()

    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
    

    传进来的对象可以为 null。

    3、常用方法

    3.1、isPresent()

    isPresent用于判断传进来的对象是否为 null

    public boolean isPresent() {
        return value != null;
    }
    

    3.2、ifPresent()

    ifPresent用于传进来的对象不为null时,则执行后续的函数式接口操作。

    public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }
    

    Consumer<? super T> consumer 即为函数式接口的标准写法,Lambda表达式是函数式编程的体现,这里用于接收Lambda表达式。后续对 Lambda表达式进行一番整理。

    3.3、filter()

    filter对对象进行过滤,如果对象为空直接返回,如果不满足条件返回空的 Optional 。

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

    3.4、map() 与flatMap()

    map() 方法类似于 Stream中的 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));
        }
    }
    
    //返回Optional<T>
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
    

    flatMap 用于对象中包含对象类型的属性的场景,例如

    public class User implements Serializable {
        @ApiModelProperty(value = "主键ID")
        @TableId(value = "id", type = IdType.AUTO)
        private Long id;
    
        private Optional<Address> address;
    }
    

    仔细看下源码,可以发现与 map()方法存在些许不同

    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));
        }
    }
    
    //返回T
    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }
    

    执行 flatMap(user -> user.getAddress())返回的是Optional<Address>

    而执行 map(user -> user.getAddress())返回的是Optional<Optional<Address>>

    所以flatMap常用于 json 字符串的字段判断。

    从网上摘抄的例子如下:

    需要取得 postcode 字段的值,常规方法是一层层判断很是麻烦,这时可以借用 flatMap

    {
        "user": {
            "age": 20,
            "name": "Jim",
            "address": {
                "province": "浙江省",
                "postcode": "111111"
            }
        }
    }
    
    JSONObject jsonObj = JSON.parseObject(json);
    
    String postcode = Optional.ofNullable(jsonObj)
            //每进入一层,返回空的Optional或相应的对象
            .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("user")))
            .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("address")))
            .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getString("postcode")))
            .orElse("unknown");
    
    System.out.println(postcode);
    

    3.5 orElse()

    当对象为 null 时,给予默认值

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

    3.6 get()

    返回对象的值,当对象为 null时,抛出异常。

    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
    

    基本用法如上,对于有不同想法的欢迎指正。

    flatmap json例子来自文章:https://blog.csdn.net/thc1987/article/details/103005587

    自我控制是最强者的本能-萧伯纳
  • 相关阅读:
    提高ASP.NET效率的几个方面
    危险字符过滤的类
    通过HttpModule实现数据库防注入
    字符串(含有汉字)转化为16进制编码进制
    C# 中的类型转换
    防范SQL注入攻击的代码
    微软笔试小感
    Debug和Trace配置小记
    C#动态地调用Win32 DLL中导出的函数
    Debug和Trace使用小记
  • 原文地址:https://www.cnblogs.com/CF1314/p/14069850.html
Copyright © 2011-2022 走看看