Elegant way of code - how to judge empty in Java

1 Introduction

In the actual project, we will have many places that need to judge the null check. If the null check is not performed, a NullPointerException may occur.

We mentioned the handling of exceptions in the previous article:

Let’s take a look at some empty judgment methods in actual projects

Usually we judge whether an object is Null, we can use Objects.nonNull(obj) in java.util, ObjectUtil in hutool or directly null != obj

2. Empty judgment of List

In a special project like List, it may not only be judged to be non-empty. For List, not equal to null and List.size() not equal to 0 are two different things. There are also interns in the company who often confuse these two. If list is not equal to null, it means that it has been initialized, and there is a piece of heap memory that belongs to it. Site, and a size of 0 means that nothing has been put into it. For example, if it is not equal to null, it means that I have a bottle now, and a size greater than 0 means that I have filled the bottle with water.

In actual projects, it is also found that list.isEmpty() is used to judge directly. Let’s take a look at the source code:

It is equivalent to judging whether there is water in the bottle (the premise is that the bottle already exists, if the bottle does not exist, a NullPointerException will be thrown).

So usually use list != null && list.size > 0 to judge, or directly use isEmpty of the CollUtil tool in HuTool. There are also Set, Map, etc.

3. String's null judgment

The concept of bottle and water is still used here. When String is null, calling equals(String) or length() will throw java.lang.NullPointerException.

There are several methods for judging empty strings:

1. One of the methods used by most people, intuitive and convenient, but inefficient:

if(a == null || a.equals(""));

2. Compare the string length, efficient:

if(a == null || a.length() == 0);

3. Java SE 6.0 has just begun to be provided, and the efficiency is similar to method 2:

if(a == null || a.isEmpty());

Of course, you can also use the org.apache.commons.lang.StringUtils tool.

StringUtils.isNotBlank(a);

* StringUtils.isNotBlank(null) = false

* StringUtils.isNotBlank("") = false

* StringUtils.isNotBlank(" ") = false

* StringUtils.isNotBlank("bob") = true

* StringUtils.isNotBlank(" bob ") = true

该工具类中还有个isNotEmpty()方法,从注释可以很明显看出二者的差别

StringUtils.isNotEmpty(a);

* StringUtils.isNotEmpty(null) = false

* StringUtils.isNotEmpty("") = false

* StringUtils.isNotEmpty(" ") = true

* StringUtils.isNotEmpty("bob") = true

* StringUtils.isNotEmpty(" bob ") = true

4、Optional

Optional的出现就是用来防止NullpointException的。常见的方法有:

  • .empty():创建一个空的Optional实例
  • .of(T t) : 创建一个Optional 实例,为null时报异常
  • .ofNullable(T t):若t 不为null,创建Optional 实例,否则创建空实例
  • isPresent() : 判断容器中是否有值
  • ifPresent(Consume lambda) :容器若不为空则执行括号中的Lambda表达式
  • orElse(T t) : 获取容器中的元素,若容器为空则返回括号中的默认值
  • orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回s 获取的值
  • orElseThrow() :如果为空,就抛出定义的异常,如果不为空返回当前对象
  • map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
  • flatMap(Function mapper):与map 类似,要求返回值必须是Optional
  • T get() :获取容器中的元素,若容器为空则抛出NoSuchElement异常

先看个常见的示例:

baseInfo类中有布尔类型的属性,是空返回false,不为空取其值,需要四行。

当使用Optional时,一行搞定,非常的优雅。

4.1 Optional对象的创建

public final class Optional<T> {
    private static final Optional<?> EMPTY = new Optional<>();
    private final T value;
    //可以看到两个构造方格都是private 私有的
    //说明 没办法在外面new出来Optional对象
    private Optional() {
        this.value = null;
    }
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
    //这个静态方法大致 是创建出一个包装值为空的一个对象因为没有任何参数赋值
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
    //这个静态方法大致 是创建出一个包装值非空的一个对象 因为做了赋值
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    //这个静态方法大致是 如果参数value为空,则创建空对象,如果不为空,则创建有参对象
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
}
复制代码

4.2使用场景

场景1:在service层中 查询一个对象,返回之后判断是否为空并做处理

场景2:使用Optional 和函数式编程,一行搞定

5、总结

每种方法的存在必然有适用的场景,有些情况下这种链式编程,虽然代码优雅了。但是,逻辑性没那么明显,可读性有所降低,大家项目中看情况酌情使用。

Guess you like

Origin juejin.im/post/7224027867084292154