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";
}
}
构建方法:
-
// 构建一个空对象
public static Optional empty() -
// 构建一个对象,不允许为空
public static Optional of(T value) -
// 构建一个对象,可能为空
public static Optional ofNullable(T value)ofNullable 一般封装数据库过来的对象
常用方法:
-
public T get() 获取对象的值,为空时抛出异常
-
public boolean isPresent() 判断对象是否存在 不建议使用。
-
public void ifPresent(Consumer<? super T> consumer) 判断对象是否为空,不为空就执行 Consumer 行为
-
public T orElse(T other) 如果对象为空,则返回 other
-
public T orElseGet(Supplier<? extends T> other) 如果对象为空,则拿Supplier 供应商的 get方法获取值
-
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){
}
}