JAVA8学习3-Optional类

3 Optional 类

​ java.util 包下解决空指针异常的类, java8之前,我们通过手动判断对否了空,但往往我们都会忘记判断,导致 NPE。Optional 是一个 value-base Class,最好不要在上面操作比较如 equals。不建议用做参数类型或成员变量,因为 optional 没有序列化。optional 通常作为方法的返回值。

​ Optional 本质就是一个容器,里面包裹一个值,值的类型是泛型。怎么构建Optional,其本身就有很多个静态构造方法:

package java.util;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public final class Optional<T> {

    private static final Optional<?> EMPTY = new Optional<>();

    private final T value;

    private Optional() {
        this.value = null;
    }
		// 构建一个空对象
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
  
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
		// 构建一个对象(不允许为空)
    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);
    }
		// 获取对象的值,为空时抛出异常
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
		// 判断对象是否存在
    public boolean isPresent() {
        return value != null;
    }

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

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

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

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

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

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

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof Optional)) {
            return false;
        }

        Optional<?> other = (Optional<?>) obj;
        return Objects.equals(value, other.value);
    }


    @Override
    public int hashCode() {
        return Objects.hashCode(value);
    }

    
    @Override
    public String toString() {
        return value != null
            ? String.format("Optional[%s]", value)
            : "Optional.empty";
    }
}

构建方法

  1. // 构建一个空对象
    public static Optional empty()

  2. // 构建一个对象,不允许为空
    public static Optional of(T value)

  3. // 构建一个对象,可能为空
    public static Optional ofNullable(T value)

    ofNullable 一般封装数据库过来的对象

常用方法

  1. public T get() 获取对象的值,为空时抛出异常

  2. public boolean isPresent() 判断对象是否存在 不建议使用。

  3. public void ifPresent(Consumer<? super T> consumer) 判断对象是否为空,不为空就执行 Consumer 行为

  4. public T orElse(T other) 如果对象为空,则返回 other

  5. public T orElseGet(Supplier<? extends T> other) 如果对象为空,则拿Supplier 供应商的 get方法获取值

  6. public Optional map(Function<? super T, ? extends U> mapper)

    映射值,跟stream.map 一样,对数据进行映射后返回本身,映射其实就是对应的数据处理后返回给本身

package cn.zxhysy.jdk8;

import java.util.Optional;

public class OptionalTest {

    public static void main(String[] args) {
        Optional<String> optional = Optional.empty();
        // 不推荐这么写
//        if(optional.isPresent()){
//            System.out.println(optional.get());
//        }

        // 推荐
        optional.ifPresent(item -> System.out.println(item));
        // 如果为空 则打印这个 world
        System.out.println(optional.orElse("world"));

        System.out.println(optional.orElseGet(() -> "你好"));
    }

}

设计一种一对多关系来模拟返回List集合。在前后端交互中,返回的List集合推荐要么有对象,要么对象长度为0,不要返回 nul l,这样前端就不用做过多判断。

package cn.zxhysy.jdk8;

public class Employee {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package cn.zxhysy.jdk8;

import java.util.List;

public class Company {

    private String name;

    private List<Employee> employees;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
}
package cn.zxhysy.jdk8;

import java.util.*;

public class OptionalTest2 {

    public static void main(String[] args) {
        Employee employee1 = new Employee();
        employee1.setName("zhangsan");

        Employee employee2 = new Employee();
        employee2.setName("lisi");

        Company company = new Company();
        company.setName("company1");

        List<Employee> employees = Arrays.asList(employee1, employee2);
        company.setEmployees(employees);

        Company companyEmpty = new Company();
        companyEmpty.setName("companyEmpty");
        // 为空
        Optional<Company> optional = Optional.ofNullable(companyEmpty);
        System.out.println(optional.map(tempCompany -> tempCompany.getEmployees()));
        // 不为空
        optional = Optional.ofNullable(company);
        // 这里就是返回List<Employee> 如果不为空,就返回 tempCompany.getEmployees(),为空就返回一个空的列表而不是null
        System.out.println(optional.map(tempCompany -> tempCompany.getEmployees())
                .orElse(Collections.emptyList()));
    }
    // 不建议这么用, 因为 optional 没有序列化
    public void test(Optional optional){
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值