// https://www.jianshu.com/p/82ed16613072
1.Optional.of(T value),传入非 null(否则会抛出 NullPointerException) 的 value 来构造一个 Optional,返回的 Optional 包含了 value 这个值。对于该方法,。
2.Optional.ofNullable(T value),该方法和可传入null值(如果为 null 的话,返回的就是 Optional.empty())
3.Optional.empty(),构造空的 Optional,即该 Optional 中不包含值。 isPresent() 方法用来判断是否包含值
get() 用来获取 Optional 包含的值(如果值不存在,即在一个Optional.empty上调用 get()方法的话,将会抛出 NoSuchElementException 异常) Optional<User> user = Optional.ofNullable(getUserById(id));
if (user.isPresent()) {
String username = user.get().getUsername();
System.out.println("Username is: " + username); // 使用 username
}
好像看着代码是优美了点 —— 但是事实上这与之前判断 null 值的代码没有本质的区别,反而用 Optional 去封装 value,
增加了代码量。所以我们来看看 Optional 还提供了哪些方法,让我们更好的(以正确的姿势)使用 Optional。
优化:
1.ifPresent
public void ifPresent(Consumer<? super T> consumer) {
if(value != null) { //如果 Optional 中有值,则对该值调用 consumer.accept,否则什么也不做。
consumer.accept(value)
}
}
所以我们可以修改为:
Optional<User> user = Optional.ofNullable(getUserById(id));
user.ifPresent(u -> System.out.println("Username is: " + u.getUsername()));
2.orElse
User user = Optional
.ofNullable(getUserById(id))
.orElse(new User(0, "Unknown"));
System.out.println("Username is: " + user.getUsername());
3.orElseGet orElseGet 与 orElse 方法的区别在于,orElseGet 方法传入的参数为一个 Supplier 接口的实现 —— 当 Optional
中有值的时候,返回值;当 Optional 中没有值的时候,返回从该 Supplier 获得的值。
User user = Optional
.ofNullable(getUserById(id))
.orElseGet(() -> new User(0, "Unknown"));
System.out.println("Username is: " + user.getUsername());
4.orElseThrow orElseThrow 与 orElse 方法的区别在于,orElseThrow 方法当 Optional 中有值的时候,返回值;
没有值的时候会抛出异常,抛出的异常由传入的 exceptionSupplier 提供。
User user = Optional
.ofNullable(getUserById(id))
.orElseThrow(() -> new EntityNotFoundException("id 为 " + id + " 的用户没有找到"));
举一个 orElseThrow 的用途:在 SpringMVC 的控制器中,我们可以配置统一处理各种异常。查询某个实体时,如果数据库中有对应的
记录便返回该记录,否则就可以抛出 EntityNotFoundException ,处理 EntityNotFoundException 的方法中我们就给客户端返回Http
状态码 404 和异常对应的信息 —— orElseThrow 完美的适用于这种场景。
@RequestMapping("/{id}")
public User getUser(@PathVariable Integer id) {
Optional<User> user = userService.getUserById(id);
return user.orElseThrow(() -> new EntityNotFoundException("id 为 " + id + " 的用户不存在"));
}
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<String> handleException(EntityNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
5.map 如果当前 Optional 为 Optional.empty,则依旧返回 Optional.empty;否则返回一个新的 Optional,
该 Optional 包含的是:函数 mapper 在以 value 作为输入时的输出值。
Optional<String> username = Optional
.ofNullable(getUserById(id))
.map(user -> user.getUsername());
System.out.println("Username is: " + username.orElse("Unknown"));
而且我们可以多次使用 map 操作:
Optional<String> username = Optional
.ofNullable(getUserById(id))
.map(user -> user.getUsername())
.map(name -> name.toLowerCase())
.map(name -> name.replace('_', ' '));
System.out.println("Username is: " + username.orElse("Unknown"));
6.flatMap flatMap 方法与 map 方法的区别在于,map 方法参数中的函数 mapper 输出的是值,然后 map 方法会使用
Optional.ofNullable 将其包装为 Optional;而 flatMap 要求参数中的函数 mapper 输出的就是 Optional。
Optional<String> username = Optional
.ofNullable(getUserById(id))
.flatMap(user -> Optional.of(user.getUsername()))
.flatMap(name -> Optional.of(name.toLowerCase()));
System.out.println("Username is: " + username.orElse("Unknown"));
7.filter filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回
这个 Optional;否则返回 Optional.empty。
Optional<String> username = Optional
.ofNullable(getUserById(id))
.filter(user -> user.getId() < 10)
.map(user -> user.getUsername());
System.out.println("Username is: " + username.orElse("Unknown")); 总结: 有了 Optional,我们便可以方便且优雅的在自己的代码中处理 null 值,而不再需要一昧通过容易忘记和麻烦的
if (object != null) 来判断值不为 null。如果你的程序还在使用 Java8 之前的 JDK,可以考虑引入 Google 的 Guava 库 ——
事实上,早在 Java6 的年代,Guava 就提供了 Optional 的实现。

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. 【转】H5 浏览器和 webview 后退缓存机制

    来源:https://juejin.im/entry/588b44a08fd9c544813ed5b3 一.背景 用户点击浏览器工具栏中的后退按钮,或者移动设备上的返回键时,或者JS执行history ...

  2. java面向对象5--内部类

    6内部类 内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. 内部类可以是静态static的,也可用public,default,protected和private修饰.(而外部顶级类 ...

  3. mongodb导出导入实例记录

    mongodb导出导入实例记录 平时很用mongodb,所以用到了,就需要去网上搜索方法,干脆将自己的实际经历记录下来,方便日后使用. # 大致需求 源库:db_name_mongo 源IP:192. ...

  4. 2019年7月25日 shell练习--PAT题目1006:换个格式输出整数(失败案例)

    让我们用字母 B 来表示“百”.字母 S 表示“十”,用 12...n 来表示不为零的个位数字 n(<),换个格式来输出任一个不超过 3 位的正整数.例如 234 应该被输出为 BBSSS123 ...

  5. 11.关于django的content_type表

    ****** Django的contenttype表中存放发的是app名称和模型的对应关系 contentType使用方式 - 导入模块 from django.contrib.contenttype ...

  6. idea编写第一个springboot程序

    1. 创建一个 springboot 项目 使用 idea 创建的基本步骤: 2. 加入父级,起步依赖 pom.xml文件内容: <?xml version="1.0" en ...

  7. XML 验证器

    XML 错误会终止您的程序 XML 文档中的错误会终止你的 XML 程序. W3C 的 XML 规范声明:如果 XML 文档存在错误,那么程序就不应当继续处理这个文档.理由是,XML 软件应当轻巧,快 ...

  8. C++ - 操作运算符

    一.操作运算符 操作运算符:在C++中,编译器有能力将数据.对象和操作符共同组成表达式,解释为对全局或成员函数的调用 该全局或成员函数被称为操作符函数,程序员可以通过重定义函数操作符函数,来达到自己想 ...

  9. php的数组

    Array 数组 PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种 ...

  10. 4、kubernetes资源清单快速入门190625

    一.资源清单概念 资源/对象的类型 工作负载型资源:Pod, ReplicaSet, Deployment, StatefulSet, DaemonSet, Job, Cronjob, ... 服务发 ...