Optional对象的创建
Optional类的部分源码
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);
}
// 1、创建一个包装对象值为空的Optional对象
Optional<String> optStr = Optional.empty();
// 2、创建包装对象值非空的Optional对象
Optional<String> optStr1 = Optional.of("optional");
// 3、创建包装对象值允许为空的Optional对象
Optional<String> optStr2 = Optional.ofNullable(null);
get()方法
get()方法主要用于返回包装对象的实际值,但是如果包装对象值为null,会抛出NoSuchElementException异常。
Category category = null;
Optional.ofNullable(category).get();
isPresent()方法
isPresent()方法用于判断包装对象的值是否非空
Category category = null;
boolean b = Optional.ofNullable(category).isPresent();
b = false
ifPresent()方法
ifPresent()方法接受一个Consumer对象(消费函数),如果包装对象的值非空,运行Consumer对象的accept()方法
Optional.ofNullable(category).ifPresent(c -> {System.out.println(c); });
filter()方法
filter()对Optional对象进行过滤,如果符合条件,返回Optional对象本身,否则返回一个空的Optional对象
Category category = new Category(){{
setCategoryName("test");
}};
Optional.ofNullable(category).filter(c -> c.getCategoryName().equals("test")).ifPresent(c ->{
System.out.println(c.getCategoryName());
});
map()方法
map()方法的源码:
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));
}
}
map()方法的参数为Function(函数式接口)对象,map()方法将Optional中的包装对象用Function函数进行运算,并包装成新的Optional对象(包装对象的类型可能改变),示例:
String name = Optional.ofNullable(category).map(c -> c.getCategoryName()).get();
flatMap()方法
flatMap()方法的源码:
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));
}
}
跟map()方法不同的是,入参Function函数的返回值类型为Optional<U>类型,而不是U类型,这样flatMap()能将一个二维的Optional对象映射成一个一维的对象。以map()方法示例功能为例,进行faltMap()改写如下
String name = Optional.ofNullable(category).flatMap(c->Optional.ofNullable(c.getCategoryName())).get();
orElse()方法
如果包装对象值非空,返回包装对象值,否则返回入参other的值(默认值)
Optional.ofNullable(category).map(c-> c.getCategoryName()).orElse("unknow");
orElseGet()方法
String str = Optional.ofNullable(category).map(student -> student.getCategoryName()).orElseGet(()->"unknow");
orElse() 与 orElseGet()区别
在分布式开发中,有一个方法需要接收前台数据,但该数据可能为空,当该数据为空时,需要远程调用一个方法为其设置默认值
public String getDefaultValue(){ //远程方法调用
System.out.println("我被调用了!");
return "我是默认值";
}
public void testSupplier(){
Optional<String> opt = Optional.of("前端数据");
String x = opt.orElse( getDefaultValue() );
System.out.println("---以上为orElse调用,以下为orElseGet调用---");
String y = opt.orElseGet( ()->getDefaultValue() );
}
运行结果
我被调用了!
---以上为orElse调用,以下为orElseGet调用---
结果为orElse调用方法,orElseGet没有调用方法
虽然opt不为空,但是orElse()依然调用了远程方法,并产生了一个String对象
orElseGet并没有调用方法,也没有产生任何对象
所以可见orElseGet()更优, 但代价就是需要传入一个Supplier<T>类型的参数
orElseThrow()方法
Optional.ofNullable(category).orElseThrow(()->new RuntimeException("unknow"));