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

1、构造方式

Optional 的三种构造方式: Optional.of(obj),  Optional.ofNullable(obj) 和 Optional.empty()

1.1、Optional.of(obj)

它要求传入的 obj 不能是 null 值的, 否则 NullPointerException.

使用场景:
1. 当我们非常非常的明确将要传给 Optional.of(obj) 的 obj 参数不可能为 null 时;  
2. 当obj 为 null 立即报告 NullPointException 异常, 而不是隐藏空指针异常时.

1.2、Optional.ofNullable(obj)

传 null 进到就得到 Optional.empty(), 非 null 就调用 Optional.of(obj).

1.3、Optional.empty()

内部value是null

2、不推荐的使用方式

  1.  
    Optional<User> user = ……
  2.  
    if (user.isPresent()) {
  3.  
    return user.getOrders();
  4.  
    } else {
  5.  
    return Collections.emptyList();
  6.  
    }
  7.  
     

这种方式和我们直接使用obj != null做判断没什么区别。实际上,当我们还在以如下几种方式使用 Optional 时, 就说明你的使用方式可能有问题:

(1)调用 isPresent() 方法时或者调用 get() 方法时。这两种方法应该认为是private的,你最好不要直接使用。
(2)Optional 类型作为类/实例属性时。Optional 类型不可被序列化, 用作字段类型会出问题
(3)Optional 类型作为方法参数时。

3、正确的使用方式

Optional 中我们真正可依赖的应该是除了 isPresent() 和 get() 的其他方法:

  1.  
    public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
  2.  
    public T orElse(T other)
  3.  
    public T orElseGet(Supplier<? extends T> other)
  4.  
    public void ifPresent(Consumer<? super T> consumer)
  5.  
    public Optional<T> filter(Predicate<? super T> predicate)
  6.  
    public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
  7.  
    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X

3.1、存在则返回数据

3.1.1、orElse

存在即返回, 无则提供默认值

return user.orElse(null);
return user.orElse(UNKNOWN_USER);

3.1.2、orElseGet

存在即返回, 无则由函数来产生

return user.orElseGet(() -> fetchAUserFromDatabase());

3.1.3、orElseThrow

存在即返回, 无则抛出supplier接口创建的异常。

try {
  empty.orElseThrow(ValueAbsentException::new);
} catch (Throwable ex) {
  System.out.println(ex.getMessage());
}

3.2、存在则执行某个动作

3.2.1、ifPresent

存在才对它做点什么

user.ifPresent(System.out::println);
 
//等同于
if (user.isPresent()) {
  System.out.println(user.get());
}

3.3、存在则转换成另一个Optional

3.3.1、map

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

如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。

  1.  
    Optional<String> name2 = Optional.of("deff");
  2.  
    Optional<String> s = name2.map((value) -> value.toUpperCase());
  3.  
    System.out.println(s.orElse("No value found"));//DEFF
  4.  
     
  5.  
     
  6.  
    Optional<String> name2 = Optional.ofNullable(null);
  7.  
    Optional<String> s = name2.map((value) -> value.toUpperCase());
  8.  
    System.out.println(s.orElse("No value found"));//No value found

//之前的做法
if(user.isPresent()) {
  return user.get().toUpperCase();
} else {
  return Collections.emptyList();
}

map  是可能无限级联的, 比如再深一层, 获得用户名的大写形式
return user.map(u -> u.getUsername())
           .map(name -> name.toUpperCase())
           .orElse(null);

3.3.2、flatMap

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。

flatMap与map(Funtion)方法类似,区别在于传入方法的lambda表达式的返回类型。
map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional。

  1.  
    Optional<String> name = Optional.of("Abc");
  2.  
    Optional<String> upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
  3.  
    System.out.println(upperName.orElse("No value found"));//ABC

3.5、存在则做过滤

3.5.1、filter

检查给定的Option值是否满足某些条件。如果满足则返回同一个Option实例,否则返回空Optional。

Optional<String> longName = name.filter((value) -> value.length() > 6)

4、总结:

用了 isPresent() 处理 NullPointerException 不叫优雅, 有了  orElse, orElseGet 等, 特别是 map 方法才叫优雅.
使用 Optional 时尽量不直接调用 Optional.get() 方法, Optional.isPresent() 更应该被视为一个私有方法, 应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法

Java8 Optional总结的更多相关文章

  1. Java8 Optional的简单操作

    我们经常会遇到这种情况:首先判断一个对象是否为null,如果不为null,获取一个对象中的一个属性,如果该属性不为null,又获取该属性的属性,如果该属性的属性不为null,又获取属性的属性的属性: ...

  2. java8 Optional优雅非空判断

    java8 Optional优雅非空判断 import java.util.ArrayList;import java.util.List;import java.util.Optional; pub ...

  3. Java8 Optional && Guava Optional

    Java8 -- Optional boolean isPresent():与obj != null()一样:调用get()前要调用isPresent()检查,不然会报错 Optional的三种构造方 ...

  4. java代码之美(16) ---Java8 Optional

    Java8 Optional 一句话介绍Optional类:使用JDK8的Optional类来防止NullPointerException(空指针异常)问题. 一.前言 在我们开放过程中,碰到的异常中 ...

  5. java8 Optional使用总结

    [前言] java8新特性 java8 函数接口 java8 lambda表达式 Java 8 时间日期使用 java8 推出的Optional的目的就是为了杜绝空指针异常,帮助开发者开发出更优雅的代 ...

  6. 聊一聊Java8 Optional,让你的代码更加优雅

    码农在囧途 随着时间的推移,曾经我们觉得重要的东西,可能在今天看来是如此的浅薄和无知,同理,今天我们放不下,想不开,觉得重要的东西,多年后我们可能也会觉得也就那样,所以,今天的的所有烦恼,忧愁,想不开 ...

  7. 使用 Java8 Optional 的正确姿势(转)

    我们知道 Java 8 增加了一些很有用的 API, 其中一个就是 Optional. 如果对它不稍假探索, 只是轻描淡写的认为它可以优雅的解决 NullPointException 的问题, 于是代 ...

  8. Java8 Optional类

    概述 到目前为止,著名的NullPointerException是导致Java应用程序失败的最常见原因.过去,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guav ...

  9. java8 Optional正确使用姿势

    Java 8 如何正确使用 Optional import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; ...

  10. java8 - Optional

    mport java.util.Optional; import org.junit.Test; /* * 一.Optional 容器类:用于尽量避免空指针异常 * Optional.of(T t) ...

随机推荐

  1. BBR加速 Centos

    BBR是什么 BBR 是 Google 提出的一种新型拥塞控制算法,可以使 Linux 服务器显著地提高吞吐量和减少 TCP 连接的延迟. BBR项目地址 https://github.com/goo ...

  2. 数据库-mysql01 简单介绍以及安装部署

    本次mysql数据库安装采用二进制安装(免安装即绿色版),数据库版本是mysql5.7.26 首先下载mysql安装包,然后上传服务器里,最后解压. 卸载centos7自带的数据库软件包: [root ...

  3. 笔试12:Bootstrap知识

    BootStrap Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷. ...

  4. jq中

    1.jquery位置信息 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  5. 面向对象程序设计(Java) 第4周学习指导及要求

    2019面向对象程序设计(Java)第4周学习指导及要求(2019.9.17-2019.9. 23)  学习目标 掌握类与对象的基础概念,理解类与对象的关系: 掌握对象与对象变量的关系: 掌握预定义类 ...

  6. 开放接口的安全验证方案(AES+RSA)

    http://wubaoguo.com/2015/08/21/%E5%BC%80%E6%94%BE%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%89%E5%85%A8%E9%AA ...

  7. USACO Score Inflation

    洛谷 P2722 总分 Score Inflation https://www.luogu.org/problem/P2722 JDOJ 1697: Score Inflation https://n ...

  8. 水晶报表报错:log4net初始值问题

    运行水晶报表的程序一直出错,报错如下: System.TypeInitializationException: “CrystalDecisions.ReportSource.ReportSourceF ...

  9. spring中@Param和mybatis中@Param使用区别(暂时还没接触)

    1.spring中@Param(org.springframework.data.repository.query.Param) int selectRoleCount(@Param("bu ...

  10. clickhouse安装 Requires: libstdc++.so.6(GLIBCXX_3.4.19)(64bit)

    问题描述: centos 用如下命令安装clickhouse时 yum install -y clickhouse-server clickhouse-client 报错: --> Runnin ...