最近接触了Optional这个类,虽说出来好久了,但之前一直没接触过,所以在这里记录一下这个类的用法
Optional介绍
java.util.Optional 是java8中引进的一个新的类,它可以对可能缺失的值进行建模,而不是直接将null赋值给变量。主要是用来避免空指针异常的
Optional 是一个对象容器,具有以下两个特点:
- 提示用户要注意该对象有可能为null
简化if else代码
创建Optional
- Optional.empty(): 创建一个空的 Optional 实例
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
- Optional.of(T t):创建一个 Optional 实例,当 t为null时抛出异常(这种应该很少用,以为使用Optional最主要就是用来避免空指针的)
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
- Optional.ofNullable(T t):创建一个 Optional 实例,但当 t为null时不会抛出异常,而是返回一个空的实例
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
获取Optional
Optional.get():获取optional实例中的对象,当optional 容器为空时报错
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
Optional的判断方法
- isPresent():判断optional是否为空,如果空则返回false,否则返回true
public boolean isPresent() {
return value != null;
}
- ifPresent(Consumer c):如果optional不为空,则将optional中的对象传给Comsumer函数
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
- orElse(T other):如果optional不为空,则返回optional中的对象;如果为null,则返回 other 这个默认值
- orElseGet(Supplier other):如果optional不为空,则返回optional中的对象;如果为null,则使用Supplier函数生成默认值other
orElse和orElseGet的源码对比
package java.util;
public final class Optional<T> {
...
public T orElse(T other) {
return this.value != null ? this.value : other;
}
public T orElseGet(Supplier<? extends T> supplier) {
return this.value != null ? this.value : supplier.get();
}
}
- orElseThrow(Supplier exception):如果optional不为空,则返回optional中的对象;如果为null,则抛出Supplier函数生成的异常
Optional过滤
filter源码
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
映射
map(Function<T, U> mapper):如果optional不为空,则将optional中的对象 t 映射成另外一个对象 u,并将 u 存放到一个新的optional容器中
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
//如果为空,就返回个空Optional
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
flatMap(Function< T,Optional<>> mapper):跟上面一样,在optional不为空的情况下,将对象t映射成另外一个optional
区别:map会自动将u放到optional中,而flatMap则需要手动给u创建一个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));
}
}
测试代码
public static void main(String[] args) {
//Student student = null; //如果是null的话,什么都不会打印
Student student = new Student(1, "xiaoming", 12);
if (student != null){
System.out.println("一般的if写法:"+student.getName());
}
//Optional普通用法(不优雅用法)
Optional<Student> optionalStudent = Optional.ofNullable(student);
if (optionalStudent.isPresent()){
Student optionalStu = optionalStudent.get();
System.out.println("Optional普通用法:"+optionalStu.getName());
}
//优雅用法
optionalStudent.ofNullable(student).map(new Function<Student, String>() {
@Override
public String apply(Student student) {
return student.getName();
}
}).ifPresent(new Consumer<String>() {
@Override
public void accept(String name) {
System.out.println(name);
}
});
//优雅lambda用法
optionalStudent.ofNullable(student).map(Student::getName).ifPresent(System.out::println);
List<String> list = Arrays.asList("a1","b2","c3");
//这里为了清楚看map和flatMap的区别,就不简写了
Optional<String> s = Optional.ofNullable(list).map(new Function<List<String>, String>() {
@Override
public String apply(List<String> list) {
StringBuffer sb = new StringBuffer();
for (String o : list) {
sb.append(o);
}
//返回值会自动放到Optional容器中
return sb.toString();
}
});
Optional<String> s1 = Optional.ofNullable(list).flatMap(new Function<List<String>, Optional<String>>() {
@Override
public Optional<String> apply(List<String>list) {
StringBuffer sb = new StringBuffer();
for (String o : list) {
sb.append(o);
}
//返回值是Optional,需要手动构建
return Optional.ofNullable(sb.toString());
}
});
}