• Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验


    场景

    Guava

    Guava 项目是 Google 公司开源的 Java 核心库,它主要是包含一些在 Java 开发中经常使用到的功能,

    数据校验、不可变集合、计数集合,集合增强操作、I/O、缓存、字符串操作等。

    并且 Guava 广泛用于 Google 内部的 Java 项目中,也被其他公司广泛使用,甚至在新版 JDK 中直接引入了 Guava 中的优秀类库

    Guava Github:

    GitHub - google/guava: Google core libraries for Java

    官方用户手册:

    Home · google/guava Wiki · GitHub

    依赖引入

    1.         <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
    2.         <dependency>
    3.             <groupId>com.google.guava</groupId>
    4.             <artifactId>guava</artifactId>
    5.             <version>30.0-jre</version>
    6.         </dependency>

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi 
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    数据校验

    数据校验一个是非空校验,一个是预期值判断。

    非空判断,就是常说的NullPointException,处理方式一般是if(x==null)的判断进行解决。

    预期值判断就是检查数据值是不是自己想要的结果。

    Optional

    在JDK8以后参考Guava加入了Optional的API,使用上与Guava区别不大。

    一个常见的例子就是对象的嵌套判空。

    1.         Company company = new Company("霸道的程序猿",null);
    2.         User user = new User("张三",50,company);
    3.         //之前if嵌套的写法
    4.         if(null!=user){
    5.             User user1 = user;
    6.             if(null!=user1.getCompany()){
    7.                 Company company1 = user1.getCompany();
    8.                 if(null!=company1.getAddress()){
    9.                     String address = company1.getAddress();
    10.                     System.out.println(address);
    11.                 }else{
    12.                     System.out.println("张三公司地址为空");
    13.                 }
    14.             }
    15.         }

    但是在使用Optional之后可以这样写

    1.         //使用optional之后
    2.         String address = Optional.ofNullable(user)
    3.                 .map(User::getCompany)
    4.                 .map(Company::getAddress)
    5.                 .orElse("默认地址");
    6.         System.out.println(address);

    注:

    ofNullable:如果user为空,则返回一个单例空Optional对象,如果非空则返回一个Optional包装对象。

    map:如果为空,继续返回第一步中的单例Optional对象,否则调用User的getCompany方法。

    orElse:获取map中的value,不为空直接返回,为空则将参数作为默认值。

    关于Optional的map等api的用法具体可参考如下

    Java8新特性-Stream对集合进行操作的常用API:

    Java8新特性-Stream对集合进行操作的常用API_霸道流氓气质的博客-CSDN博客_javalist.stream

    获取Optional对象的方法

    1、获取一个空的Optional对象,里面没有值。

    Optional<User> optional = Optional.empty();

    2、获取一个值非空的Optional对象,如果参数为空则报NullPointException

    Optional<User> optional1 = Optional.of(new User());

    3、返回一个可以为空也可以非空的Optional对象,如果参数为空则通过Optional.empty返回一个Optional对象。

    Optional<User> optional2 = Optional.ofNullable(null);

    Optional的常用方法

    1、isPresent方法表示判断Optional对象中是否存储的为空值,如果存储为空值那么返回false,否则返回true。

    1.         User user = new User();
    2.         Optional<User> optionalUser= Optional.of(user);
    3.         System.out.println("user是否为空:"+optionalUser.isPresent());//返回true
    4.         User user1 = new User("霸道的程序猿",50,new Company());
    5.         Optional<User> optionalUser1= Optional.of(user1);
    6.         System.out.println("user1是否为空:"+optionalUser1.isPresent());//返回true
    7.         User user2 = null;
    8.         Optional<User> optionalUser2= Optional.ofNullable(user2);
    9.         System.out.println("user1是否为空:"+optionalUser2.isPresent());//返回false

    2、get方法返回Optional的引用,若引用缺失则抛出illegalStateException

    1.         Optional<Integer> optionalInteger = Optional.of(5);
    2.         System.out.println(optionalInteger.get());//返回5

    3、ifPresent方法,如果optional对象保存的值不是null,则调用参数并执行操作,否则不执行

    1.         User user3 = new User("张三", 20, new Company());
    2.         Optional<User> optionalUser3 = Optional.of(user3);
    3.         optionalUser3.ifPresent(u -> System.out.println(u.getName()));//执行
    4.         Optional<User> optionalUser4 = Optional.ofNullable(null);
    5.         optionalUser4.ifPresent(u -> System.out.println(u.getName()));//不执行

    4、orElse()方法中如果optional中存储的值不是null则返回这个值,如果是null则返回传入的值

    1.         User user4 = optionalUser4.orElse(new User("默认",50,new Company()));
    2.         System.out.println(user4.getName());//返回默认
    3.         optionalUser3.orElse(new User("默认",50,new Company()));
    4.         System.out.println(user3.getName());//返回张三

    Preconditions

    Guava在Preconditions类中提供了若干前置条件判断的实用方法。

    比如在如下方法参数校验时

    1.     private void testPreconditions(User user, String param,Boolean ifAllow){
    2.         if(!ifAllow){
    3.             throw new IllegalArgumentException("不被允许");
    4.         }
    5.         if(param ==null){
    6.             throw new NullPointerException("param为空");
    7.         }
    8.         if(user!=null && user.getAge() == 0){
    9.             throw new IllegalArgumentException("user.getAge() == 0");
    10.         }
    11.     }

    通过使用Preconditions,期望能尽早抛出异常,而不是等数据被层层传递,传递到非常深的位置,

    这样浪费系统资源更不利于我们开发定位错误。所以推荐在方法的入口或运算开始前,先检查数据。

    所以上面的校验可以用Preconditions修改为

    1.     private void testPreconditions2(User user, String param,Boolean ifAllow){
    2.         //Preconditions.checkArgument(ifAllow,"不被允许");
    3.         Preconditions.checkArgument(user.getAge()!=0,"user.getAge() == 0");
    4.         //Preconditions.checkNotNull(param,"param为空");
    5.     }

    Preconditions的常用方法

     

    方法使用示例代码

    1.     private void testPreconditions2(User user, String param,Boolean ifAllow){
    2.         //Preconditions.checkArgument(ifAllow,"不被允许");
    3.         Preconditions.checkArgument(user.getAge()!=0,"user.getAge() == 0");
    4.         //Preconditions.checkNotNull(param,"param为空");
    5.     }
    6.     private void testPreconditions3(int index){
    7.         int[] array = {1,2,3,4,5};
    8.         Preconditions.checkElementIndex(index,array.length,"数组越界");
    9.     }
    10.     private void testPreconditions4(int index){
    11.         int[] array = {1,2,3,4,5};
    12.         Preconditions.checkPositionIndex(index,array.length,"数组越界");
    13.     }
    14.     private void testPreconditions5(User user){
    15.         Preconditions.checkState(user.getAge()!=0,"user.getAge()=0");
    16.     }
    17.     @Test
    18.     public void test3(){
    19.         //testPreconditions(new User("zhangsan",0,new Company()),null,false);
    20.         //testPreconditions2(new User("zhangsan",0,new Company()),null,false);
    21.         //testPreconditions3(0);//通过
    22.         //testPreconditions3(5);//不通过
    23.         //testPreconditions4(0);//通过
    24.         //testPreconditions4(5);//通过
    25.         //testPreconditions4(6);//不通过
    26.         testPreconditions5(new User("zhangsan",0,new Company()));//不通过
    27.     }

  • 相关阅读:
    Java 框架的一些文件配置
    领域内容第18名
    密码学【对称加密-DES\AES】
    [附源码]JAVA毕业设计公务用车管理智慧云服务监管平台(系统+LW)
    Intelligence X功能介绍丨搜索引擎丨数据存储
    JQ css操作 动画
    Selenium-介绍下其他骚操作
    Flask数据库操作-Flask-SQLAlchemy
    不要只会刷d音了
    毕设(5)—笛卡尔空间轨迹规划(直线、圆弧)
  • 原文地址:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127683387