让代码变优雅系列之《一》-----Optional<T>结合Lambda

    xiaoxiao2022-07-07  210

    起因:

    一个项目中必不可少的代码可能长这样:

    Order order = orderCourseMapper.selectByPrimaryKey(vo.getOrderId()); if(order == null) throw new OrderException(ErrorCode.ERROR_NOCOURSEORDER); if(order.getStatus() != null && order.getStatus() !=DBConstant.OrderStatus.ALREADY) throw new OrderException(ErrorCode.ERROR_NOTCOMPLETEORDER);

    可以看到,对于Order属性status我做了两个if判断,就是为了防止NullPointerException,在有些业务场景下,甚至还需要更多的if判空,这就是我们常说的“判空炸弹”,这样会使我们的代码很不优雅,可读性很差!

    解决:java8新特性之Optional

    上面的代码用Optional可以这么写:

    Order order = orderCourseMapper.selectByPrimaryKey(vo.getOrderId()); if(Optional.ofNullable(order) .map(m -> m.getStatus()) .orElseThrow(() -> new OrderException(ErrorCode.ERROR_ARG)) !=DBConstant.OrderStatus.ALREADY) throw new OrderException(ErrorCode.ERROR_NOTCOMPLETEORDER);

    好像代码没有简洁多少,但是代码更优雅了不是吗?好吧,我承认我就喜欢这样另类的风格!!!

     

    下面介绍下Optional:

    Optional类是Java8为了解决null值判断问题,借鉴google guava类库的Optional类而引入的一个同名Optional类。

    它的部分源码长这样:

    private static final Optional<?> EMPTY = new Optional<>(); private final T value; private Optional() { this.value = null; } public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; } 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); }

    由于构造方法都是私有的,只能通过调用静态方法来构造对象,对于项目中常用的应该是Optional.ofNullable(T)--创建允许包装对象值为null的Optional对象

    常用的方法有:

    1>Optional.ofNullable(order).ifPresent(o ->System.out.println(“消费函数”))

    只有当order不为null时才会执行消费函数

    2>Optional.ofNullable(order).map(o -> o.getCode()).orElse("未找到"))

    order为null返回“未找到”,否则返回order.getCode();

    3>Optional.ofNullable(order).map(o -> o.getCode()).orElseGet(() ->System.out.println(“未找到”)))

    4>Optional.ofNullable(order).map(o -> o.getCode()).orElseThrow(() -> new OrderException(ErrorCode.ERROR_ARG)))

    orElseThrow()方法适用于包装对象值为空时需要抛出特定异常的场景

     

     

    ps:Optional比较适合复杂对象,特别是多重嵌套对象的多重判断。

    像这样:

    Optional.ofNullable(new Person())

    .map(x->x.country)

    .map(x->x.provinec)

    .map(x->x.city)

    .map(x->x.name)

    .orElse("unkonwn");

     这里用Optional作为每一次返回的外壳,如果有某个位置返回了null,则会直接得到"unkonwn"。

    对于单个值的判断,其实没有体现太多优势!

    对我来说,项目中应用的场景大概就是这样:

    //直接查询对象,当对象为null时,抛出自定义异常 Order order = Optional.ofNullable(orderCourseMapper.selectByPrimaryKey(vo.getOrderId())) .orElseThrow(() -> new OrderException(ErrorCode.ERROR_NOCOURSEORDER));

     

    最新回复(0)