zoukankan      html  css  js  c++  java
  • java8--- Optional使用

     

       // 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<String> emptyOpt = Optional.empty();  // 创建一个没有值的Optional对象。
           empty()方法创建的对象没有值,如果对emptyOpt变量调用isPresent()方法会返回false,调用get()方法抛出NullPointerException异常。

      正确的示例:
            // 当Optional的值通过常量获得或者通过关键字new初始化,可以直接使用of()方法
          Optional<String> strOpt = Optional.of("Hello World");
          Optional<User> userOpt = Optional.of(new User());

          // 方法参数中role值不确定是否为null,使用ofNullable()方法创建
          Optional<Role> roleOpt = Optional.ofNullable(role);

    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()));

      使用orElse()方法获取值

       2.orElse:  如果有值就返回,否则返回一个给定的值作为默认值
             User user = Optional
                .ofNullable(getUserById(id))
                .orElse(new User(0, "Unknown"));
             System.out.println("Username is: " + user.getUsername());

        示例1: 判断字符串str是否为空,不为空就返回,否则,返回一个常量。:
        return str != null ? str : "Hello World" 优化: return Optional.ofNullable(str).orElse("Hello World")

        示例2:
          User user = ...
          if (user != null) {
              String userName = user.getUserName();
              if (userName != null) {
                  return userName.toUpperCase();
              } else {
                  return null;
              }
          } else {
              return null;
          }


          ========>

          User user = ...
          Optional<User> userOpt = Optional.ofNullable(user);

          return userOpt.map(User::getUserName)
                  .map(String::toUpperCase)
                  .orElse(null);
        

    3.orElseGet: 与orElse()方法作用类似,区别在于生成默认值的方式不同。该方法接受一个Supplier<? extends T>函数式接口参数,当 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 的实现。
  • 相关阅读:
    前端 一——介绍
    python知识点拾遗
    python 五——自定义线程池
    python 四——线程、进程、协程
    python 三——列表、字典、元祖、字符串、set
    动态规划法求解0-1背包
    贪心法求解背包问题
    学生成绩管理系统
    [C语言练习]学生学籍管理系统
    [C语言练习]万年历加强版
  • 原文地址:https://www.cnblogs.com/hahajava/p/12092827.html
Copyright © 2011-2022 走看看