Optional
简单介绍
Optional类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在使用Optional类可以更好的表达这个概念,并且它还可以避免空指针异常。
方法源码及示例
- of
/**
* 创建一个Optional容器
* Returns an {@code Optional} with the specified present non-null value.
*
* @param <T> the class of the value
* @param value the value to be present, which must be non-null
* @return an {@code Optional} with the value present
* @throws NullPointerException if value is null
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
示例:
注意:of()方法中传入null,会报NullPointerException异常
// 值可以为空
List<String> list = new ArrayList<>();
Optional<List<String>> optional = Optional.of(list);
System.out.println(optional.get()); // []
// ......
// 值不可以为null
Optional<List<String>> optional = Optional.of(null);
System.out.println(optional.get()); // Exception in thread "main" java.lang.NullPointerException
- empty
/**
* 创建一个空的Optional实例,即里面没有任何的东西.
* Returns an empty {@code Optional} instance. No value is present for this
* Optional.
*
* @apiNote Though it may be tempting to do so, avoid testing if an object
* is empty by comparing with {@code ==} against instances returned by
* {@code Option.empty()}. There is no guarantee that it is a singleton.
* Instead, use {@link #isPresent()}.
*
* @param <T> Type of the non-existent value
* @return an empty {@code Optional}
*/
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
示例:
empty()方法只是构建一个空的Optional,里面没有任何的东西
Optional<User> optional = Optional.empty();
System.out.println(optional.get());
- ofNullable
/**
* 创建一个包装有该对象的Optional实例,相当于empty 和 of 的整合
* Returns an {@code Optional} describing the specified value, if non-null,
* otherwise returns an empty {@code Optional}.
*
* @param <T> the class of the value
* @param value the possibly-null value to describe
* @return an {@code Optional} with a present value if the specified value
* is non-null, otherwise an empty {@code Optional}
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
示例:
虽然Optional类中的of()方法不允许包装null,但是ofNullable()方法可以,传递到该方法中的若为null,则构建一个空的Optional实例;传递到该方法中的若为一个对象,则构建一个包装有该对象的Optional实例。实际上,ofNullable()方法是empty()方法和of()方法它俩的综合。一般配合OrElse使用,处理对象为null的情况。
List<String> list = new ArrayList<>();
list.add("James");
List<String> result = Optional.ofNullable(list.stream().filter(item -> (item.equals("James"))).collect(Collectors.toList()))
.orElse(new ArrayList<>());
System.out.println(result.get(0)); // James
- ifPresent
/**
*
* If a value is present, invoke the specified consumer with the value,
* otherwise do nothing.
*
* @param consumer block to be executed if a value is present
* @throws NullPointerException if value is present and {@code consumer} is
* null
*/
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
示例:
如果值存在则使用该值调用 consumer , 否则不做任何事情。
QueryWrapper<Gallery> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("app_id", appId);
List<Gallery> galleries = this.getBaseMapper().selectList(queryWrapper);
List<GalleryVo> resultVo = new ArrayList<>();
Optional.ofNullable(galleries).ifPresent(result -> {
result.forEach(item -> resultVo.add(GalleryVo.asVo(item)));
});
return resultVo;
- orElse
/**
* 如果调用对象包含有值,不为null,那么返回该值,否则返回orElse()方法中的对象other。
* Return the value if present, otherwise return {@code other}.
*
* @param other the value to be returned if there is no value present, may
* be null
* @return the value, if present, otherwise {@code other}
*/
public T orElse(T other) {
return value != null ? value : other;
}
示例:
如果调用对象不为null,那么返回该值,否则返回orElse()方法中的对象。同上
List<String> list = null;
List<String> list1 = new ArrayList<>();
list1.add("James");
List<String> result = Optional.ofNullable(list)
.orElse(list1);
// list为null,因此返回orElse中的list1对象
System.out.println(result); // [James]
- orElseGet
/**
* 如果调用对象包含有值,那么返回该值,否则返回orElseGet()方法中的供给函数获取的值。
* Return the value if present, otherwise invoke {@code other} and return
* the result of that invocation.
*
* @param other a {@code Supplier} whose result is returned if no value
* is present
* @return the value if present otherwise the result of {@code other.get()}
* @throws NullPointerException if value is not present and {@code other} is
* null
*/
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
示例:
如果调用对象包含为null,那么返回该值,否则返回orElseGet()方法中的供给函数获取的值。
List<String> list = null;
ArrayList<String> list1 = new ArrayList<>();
list1.add("James");
List<String> result = Optional.ofNullable(list)
.orElseGet(()->list1);
System.out.println(result); // [James]
orElse和orElseGet的区别:
当返回的Optonal的值是空值时,无论orElse还是orElseGet都会执行;而当返回的Optional有值时,orElse会执行,而orElseGet不会执行。
public static void main(String[] args) {
List<Integer> list = Arrays.asList();
//通过reduce方法得到一个Optional类
int a = list.stream().reduce(Integer::sum).orElse(get("a"));
int b = list.stream().reduce(Integer::sum).orElseGet(() -> get("b"));
System.out.println("a "+a);
System.out.println("b "+b);
}
public static int get(String name){
System.out.println(name+"执行了方法");
return 1;
}
// 结果
// a执行了方法
// b执行了方法
// a的值:1
// b的值:1
- orElseThrow
/**
* 如果调用对象包含有值,那么返回该值,否则抛出orElseThrow()方法中的异常
* Return the contained value, if present, otherwise throw an exception
* to be created by the provided supplier.
*
* @apiNote A method reference to the exception constructor with an empty
* argument list can be used as the supplier. For example,
* {@code IllegalStateException::new}
*
* @param <X> Type of the exception to be thrown
* @param exceptionSupplier The supplier which will return the exception to
* be thrown
* @return the present value
* @throws X if there is no value present
* @throws NullPointerException if no value is present and
* {@code exceptionSupplier} is null
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
示例:
这里,如果 list 值为 null,会抛出 TemplateHomeException()自定义异常。
这个方法让我们有更丰富的语义,可以决定抛出什么样的异常,而不总是抛出NullPointerException,更具灵活性。
// orElseThrow()会在对象为空的时候抛出异常,而不是返回备选的值它会在对象为空的时候抛出异常,而不是返回备选的值
List<String> list = new ArrayList<>();
list.add("James");
List<String> result = Optional.ofNullable(list.stream().filter(item -> (item.equals("James"))).collect(Collectors.toList()))
.orElseThrow(()->{
return new TemplateHomeException("这里是自定义异常!!!");
});
System.out.println(result);
- map
/**
* 若有值则对其处理,并返回处理后的Optional;否则返回Optional.empty()。
* If a value is present, apply the provided mapping function to it,
* and if the result is non-null, return an {@code Optional} describing the
* result. Otherwise return an empty {@code Optional}.
*
* @apiNote This method supports post-processing on optional values, without
* the need to explicitly check for a return status. For example, the
* following code traverses a stream of file names, selects one that has
* not yet been processed, and then opens that file, returning an
* {@code Optional<FileInputStream>}:
*
* <pre>{@code
* Optional<FileInputStream> fis =
* names.stream().filter(name -> !isProcessedYet(name))
* .findFirst()
* .map(name -> new FileInputStream(name));
* }</pre>
*
* Here, {@code findFirst} returns an {@code Optional<String>}, and then
* {@code map} returns an {@code Optional<FileInputStream>} for the desired
* file if one exists.
*
* @param <U> The type of the result of the mapping function
* @param mapper a mapping function to apply to the value, if present
* @return an {@code Optional} describing the result of applying a mapping
* function to the value of this {@code Optional}, if a value is present,
* otherwise an empty {@code Optional}
* @throws NullPointerException if the mapping function is null
*/
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));
}
}
示例:
若有值则对其处理,并返回处理后的Optional;否则返回Optional.empty()。
TemplateHome templateHome = new TemplateHome();
templateHome.setAppId("123456");
templateHome.setName("asdf");
Optional<String> result = Optional.ofNullable(templateHome)
.map((s)->s.getAppId());
System.out.println(result.get()); // 123456
- flatMap
/**
* 与map类似,但要求返回值必须是Optional
* If a value is present, apply the provided {@code Optional}-bearing
* mapping function to it, return that result, otherwise return an empty
* {@code Optional}. This method is similar to {@link #map(Function)},
* but the provided mapper is one whose result is already an {@code Optional},
* and if invoked, {@code flatMap} does not wrap it with an additional
* {@code Optional}.
*
* @param <U> The type parameter to the {@code Optional} returned by
* @param mapper a mapping function to apply to the value, if present
* the mapping function
* @return the result of applying an {@code Optional}-bearing mapping
* function to the value of this {@code Optional}, if a value is present,
* otherwise an empty {@code Optional}
* @throws NullPointerException if the mapping function is null or returns
* a null result
*/
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类似,但要求返回值必须是Optional。
注:Java 9 为 Optional 类添加了三个方法:or()、ifPresentOrElse() 和 stream(),有兴趣的童鞋们了解一下!!!
总结
Optional 是 Java 语言的有益补充 —— 它旨在减少代码中的 NullPointerExceptions,虽然还不能完全消除这些异常。
它也是精心设计,自然融入 Java 8 函数式支持的功能。推荐使用!!!
- 程序创建简单
- 代码可读性更强
- 出错更少