Java8 Optional用法详解

起因

Optional字面上意思是可选择的,主要是java新增用来防止空异常的类,Optional是容器类,存储单元素,通过这个类来包装对象来简化对被包装对象的判空、取值操作。

Optional类可以帮助简化判空但是还是无法避免NPE,需要我们提升自身对代码空值的敏感度。

Optional基本方法

1.两种方式的静态构造方法。

第一种不可传入空值,传入空值会报NPE。

	public static <T> Optional<T> of(T value) {
	    return new Optional<>(value);
	}

第二种可传入空值。

	public static <T> Optional<T> ofNullable(T value) {
	    return value == null ? empty() : of(value);
	}

2.isPresent判断Optional内对象是否为空。不为空返回true,为空返回false。

    public boolean isPresent() {
        return value != null;
    }

判断Optional容器内对象,有值就执行Consumer函数,否则什么都不做。

	public void ifPresent(Consumer<? super T> consumer) {
	    if (value != null)
	        consumer.accept(value);
	}

3.get获取容器内对象的值。如果为空,则抛出NoSuchElementException异常。

    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

4.filter过滤方法,一般用于判断容器中的值是否与预测的值一样,有值就执行Predicate函数,Predicate返回true,返回当前对象,否则返回EMPTY对象。没值返回自身对象。

    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }

5.map映射的意思,判断当前容器中对象是否为空,如果为空返回EMPTY,否则就返回包装了Function函数返回结果的容器类Optional。

    public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }

6.flatMap与上面的方法相似只不过在Function函数中需要自己将对象封装到Optional。

    public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }

7.orElse获取容器中的对象。判断容器中对象是否为空,不为空返回对象,否则返回默认值。

    public T orElse(T other) {
        return value != null ? value : other;
    }

8.orElseGet获取容器中的对象。判断容器中对象是否为空,不为空返回对象,否则返回Supplier函数返回的值。

    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }

9.orElseThrow获取容器中的对象。判断容器中对象是否为空,不为空返回对象,否则抛出Supplier函数返回的异常。

    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }

核心用法

1.尽量少用isPresentget方法,多使用orElseorElseGetorElseThrow简化if判断。
使用Optional前

    if (null != father) {
        return father;
    } else {
        return new Father();
    }

使用Optional改写后

	return Optional.ofNullable(father).orElseGet(Father::new);

2.根据具体场景,多使用map来简化开发。
使用Optional前

	if(user != null) {
	  String name = user.getUsername();
	  if(name != null) {
	    return name.toUpperCase();
	  } else {
	    return null;
	  }
	} else {
	  return null;
	}

使用Optional后

	return user.map(User::getUsername).map(String::toUpperCase).orElse(null);

又或者是这样

	if (father == null || father.getName == null) {
	    Value = father.getName;
	} else {
	    value = "DEFAULT";
	}

使用Optional后

	value = Optional.ofNullable(father).map(Father::getName).orGet("DEFAULT");

参考资料

jdk8 Optional类源码

原创文章 10 获赞 3 访问量 2530

猜你喜欢

转载自blog.csdn.net/NestorBian/article/details/103467832