zoukankan      html  css  js  c++  java
  • 1、JAVA8 之 Optional 详解

    前言  

      相信不少小伙伴已经被java的NPE(Null Pointer Exception)所谓的空指针异常搞的头昏脑涨, 有大佬说过“防止 NPE,是程序员的基本修养。”但是修养归修养,也是我们程序员最头疼的问题之一,那么我们今天就要尽可能的利用Java8的新特性 Optional来尽量简化代码同时高效处理NPE(Null Pointer Exception 空指针异常)

    认识 Optional

    1、ofNullable 、orElse、isPresent 和 ifPresent

      Java 8 提供了判空写法:

    Optional.ofNullable(对象).orElse(为空时的逻辑).ifPresent(不为空是的逻辑);
    boolean isNull = Optional.ofNullable(对象).isPresent(); // 如果为空返回 false;不为空返回 true

      ofNullable 中的对象是一个可为空的对象(这个对象可以包含任意类型:Integer、Object、List、Map 等等),如果为空则执行 orElse 里面的逻辑,不为空则执行 ifPresent 里面的逻辑;也可以直接通过 isPresent() 来判断当前对象是否为空。直接上例子吧:

    //求字符串 s 的长度( 为空的时候返回0 )
    String str = getKey();
    if (StringUtils.isBlank(str)) {
        return 0;
    } else {
        return str.length();
    }
    // 新版 JDK 用法
    return Optional.ofNullable(str).orElse("").length();
    // 或者
    if (Optional.ofNullable(str).isPresent()) {
        return str.length();
    }
    // 或者
    Optional.ofNullable(str).ifPresent(s -> System.out.println("长度"+s.length());

      循环遍历List 集合

    // 原来常规写法
    List<String> list = getList();
    
    if (list != null) {
      for(String s: list){
          System.out.println(s);
      }
    }
    // 新版 JDK 写法
    Optional.ofNullable(list).orElse(new ArrayList<>()).forEach(o -> System.out.println(o));

    2、filter

      用于对给定的对象进行过滤

      filter()方法大致意思是,接受一个对象,然后对他进行条件过滤,如果条件符合则返回Optional对象本身,如果不符合则返回空Optional

    Person person=new Person();
    person.setAge(2);
    Optional.ofNullable(person).filter(p -> p.getAge()>50)

      再看一个根据基本的电子邮箱验证来决定接受或拒绝 User(用户) 的示例

    @Test
    public void whenFilter_thenOk() {
        User user = new User("anna@gmail.com", "1234");
        Optional<User> result = Optional.ofNullable(user)
          .filter(u -> u.getEmail() != null && u.getEmail().contains("@"));
    
        assertTrue(result.isPresent());
    }

      如果通过过滤器测试,result 对象会包含非空值。

    3、map

      map()方法将对应Funcation函数式接口中的对象,进行二次运算,封装成新的对象然后返回在Optional中

    Person person1=new Person();
    person.setAge(2);
    // 返回具体内容
    String optName = Optional.ofNullable(person).map(p -> person.getName()).orElse("name为空");
    // 返回到 optional 中
    Optional<Object> optName = Optional.ofNullable(person).map(p -> Optional.ofNullable(p.getName()).orElse("name为空"));

    4、orElseThrow()

      这个我个人在实战中也经常用到这个方法,方法作用的话就是如果为空,就抛出你定义的异常,如果不为空返回当前对象,在实战中所有异常肯定是要处理好的,为了代码的可读性

    //简单的一个查询
    Member member = memberService.selectByPhone(request.getPhone());
    Optional.ofNullable(member).orElseThrow(() -> new ServiceException("没有查询的相关数据"));

    差异对比

    1、orElse() 和 orElseGet() 的不同之处

      乍一看,这两种方法似乎起着同样的作用。然而事实并非如此。我们创建一些示例来突出二者行为上的异同。

    @Test
    public void givenEmptyValue_whenCompare_thenOk() {
        // 第一种情况
        User user = null;
        // 第二种情况
        User user = new User("john@gmail.com", "1234");
        logger.debug("Using orElse");
        User result = Optional.ofNullable(user).orElse(createNewUser());
        logger.debug("Using orElseGet");
        User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
    }
    
    private User createNewUser() {
        logger.debug("Creating New User");
        return new User("extra@gmail.com", "1234");
    }

      打印输出结果如下:

    // 第一种情况
    Using orElse
    creating user
    Using orElseGet
    creating user
    
    // 第二种情况
    Using orElse
    creating user
    Using orElseGet

      这个示例中,两个 Optional  对象都包含非空值,两个方法都会返回对应的非空值。不过,orElse() 方法仍然创建了 User 对象。与之相反,orElseGet() 方法不创建 User 对象。

      在执行较密集的调用时,比如调用 Web 服务或数据查询,这个差异会对性能产生重大影响

      且需要注意:orElse 内部可以直接写对应的方法或函数;orElseGet 内部必须要有对应的参数即使空也需要写一个空的括号,注意对比下:

    User result = Optional.ofNullable(user).orElse(createNewUser());
    User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
  • 相关阅读:
    zend guard加密使用方法
    在网页中嵌入任意字体(特殊字体/自定义字体)的解决方案
    lamp一键安装包
    PHP错误“This file has expired”的解决方法
    php采集
    smarty建的mvc环境
    sql语句操作数据库重复数据
    古语:花繁柳密处拨得开,才是手段;风狂雨急时立的定,方显脚跟。
    获取日期的jquery.ui.datepicker
    el表达式简介
  • 原文地址:https://www.cnblogs.com/liang1101/p/14664488.html
Copyright © 2011-2022 走看看