目录
[2.1 Optional.of(value)](#2.1 Optional.of(value))
[2.1.1 使用案例](#2.1.1 使用案例)
[2.2 Optional.ofNullable(value)](#2.2 Optional.ofNullable(value))
[2.2.1 使用案例](#2.2.1 使用案例)
[2.3 Optional.empty()](#2.3 Optional.empty())
[2.3.1 使用案例](#2.3.1 使用案例)
[3.1 isPresent](#3.1 isPresent)
[3.1.1 使用案例](#3.1.1 使用案例)
[3.2 ifPresent](#3.2 ifPresent)
[3.2.1 使用案例](#3.2.1 使用案例)
[3.3 orElse](#3.3 orElse)
[3.3.1 使用案例](#3.3.1 使用案例)
[3.4 orElseGet](#3.4 orElseGet)
[3.4.1 使用案例](#3.4.1 使用案例)
[3.4.2 orElse和orElseGet的区别](#3.4.2 orElse和orElseGet的区别)
[3.5 orElseThrow](#3.5 orElseThrow)
[3.5.1 使用案例](#3.5.1 使用案例)
[3.6 map](#3.6 map)
[3.6.1 使用案例](#3.6.1 使用案例)
[3.7 filter](#3.7 filter)
[3.7.1 使用案例](#3.7.1 使用案例)
[3.8 or](#3.8 or)
[3.8.1 使用案例](#3.8.1 使用案例)
[3.9 stream](#3.9 stream)
[3.9.1 使用案例](#3.9.1 使用案例)
一、Optional简介
Optional是java1.8引入的容器对象,它提供了非常丰富的API,主要是用于解决空指针异常的问题。
优点
1、清晰的表明变量值
2、丰富的API,增加了对空指针明确处理逻辑
3、提高了代码的强壮型
缺点
1、代码过于冗长
2、逻辑性不明显,代码易读性降低
3、引入了多一个对象的开销
二、构建Optional对象三种方式
2.1 Optional.of(value)
java
/**
* 返回一个Optional给定的非null值
* @param <T> 值类型
* @param value 描述的值,必须是非null
* @return 返回Optional对象
* @throws 如果value为空,抛出空指针异常
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
2.1.1 使用案例
java
Optional<String> optional = Optional.of("hello optional");
System.out.println(optional.get()); //输出hello optional
2.2 Optional.ofNullable(value)
java
/**
* 返回一个描述给定值的Optional,如果不为null,则返回一个有值的Optional对象
* @param <T> 值类型
* @param value 描述的值,可能为null
* @return 返回Optional对象,如果值为null,就返回一个null的Optional对象
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
2.2.1 使用案例
java
Optional<String> optional11 = Optional.ofNullable("hello optional222");
Optional<String> optional2 = Optional.ofNullable(null);
System.out.println("optional12:"+optional11.get());//输出hello optional222
System.out.println("optional1:"+optional2.get());//抛出.NoSuchElementException异常,不存在任何值
2.3 Optional.empty()
java
/**
* 返回一个空的Optional实例,此Optional没有值
* @param <T> 不存在的类型值
* @return 返回一个空的Optional
*/
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
2.3.1 使用案例
java
Optional<String> optional3 = Optional.empty();
System.out.println(optional2.get());//抛出.NoSuchElementException异常,不存在任何值
三、Optional常用的api解析和使用案例
3.1 isPresent
含义:判断Optional对象是否包含非空值
java
/**
* 如果存在值就返回true,如果不存在就返回false
*/
public boolean isPresent() {
return value != null;
}
3.1.1 使用案例
java
Optional<String> optional = Optional.of("hello optional");
if(optional.isPresent()){
System.out.println("当前的option不为空,输出为:"+optional.get()); //输出hello optional
}
3.2 ifPresent
如果Optional非空值,则执行传入操作
java
/**
* 如果Optional对象存在值,则执行给定的操作,否则不执行任何操作
*/
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
3.2.1 使用案例
java
Optional<String> optional11 = Optional.ofNullable("hello optional222");
String str = "string string";
optional11.ifPresent(o -> System.out.println(str));//输出string string
3.3 orElse
如果Optional有值就将其返回,否则返回orElse方法传入的值
java
/**
* 如果存在值,则返回该值,否则返回other
* 参数:可以为任意值,也可以为null
*/
public T orElse(T other) {
return value != null ? value : other;
}
3.3.1 使用案例
java
String s = null;
String optionStr = Optional.ofNullable(s).orElse("java");
System.out.println("optionStr:"+optionStr); //optionStr为空所以输出java
3.4 orElseGet
如果Optional有值,则将其返回,如果Optional没有值的时候,返回从该Supplier获得的值
java
/**
* 如果存在值,则返回该值,否则返回由函数提供的结果
* 参数:需要返回的函数
*/
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
3.4.1 使用案例
java
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
User user = null;
user = Optional.ofNullable(user).orElseGet(()->{
User user1 = new User();
user1.setName("java");
return user1;
});
System.out.println("user:"+user.getName()); //输出 user:java
}
3.4.2 orElse和orElseGet的区别
orElse和orElseGet不同之处在于当ofNullable()传入的参数不为null时,orElse方法仍然创建了other这个对象。与之相反,orElseGet方法不创建对象。在执行密度调佣时,比如web服务或者数据查询,这个差异会对性能产生重大影响。而且我们还可以在orElseGet方法中加一些日志,可以把这种为空的情况给暴露出来,所以orElse和orElseGet比起来,orElseGet性能和效率都比orElse要强。
3.5 orElseThrow
如果存在则返回该值,否则为空的话可以抛出自定义异常
java
/**
* 如果存在值,则返回该值,否则抛出由异常函数提供的异常
* 参数:exceptionSupplier 产生要抛出异常的提供函数
* 参数类型:X-引发的异常
* 抛出:如果不存在任何值,抛出NullPointerException,如果不存在任何值并且异常函数提供为null
* 注意点:带有空参数列表的对异常构造函数的方法引用可用作提供者
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
3.5.1 使用案例
java
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
User user = new User();
user.setName("java");
User user1 = Optional.ofNullable(user).orElseThrow(()->{
return new RuntimeException(); //因为user有值,所以不会抛出异常
});
System.out.println("user1:"+user1.getName()); // 输出user1:java
user = null;
User user2 = Optional.ofNullable(user).orElseThrow(()->{
return new RuntimeException(); //因为user为空,抛出需要返回的异常,这里为运行时异常
});
}
3.6 map
如果当前为Optional.empty,则依旧返回Optional.empty;否则返回一个新的Optional,该Optional函数包含的是:函数mapper在以value作为输入时的输出值,而且我们可以多次使用mapper操作
java
/**
* 如果存在值,则返回一个Optional,将给定映射函数应用于该值的结果,否则返回一个空的Optional
* 如果映射函数返回null结果,则此方法返回空的Optional
*/
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));
}
}
3.6.1 使用案例
java
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
User user = new User();
user.setName("java");
Optional<String> optionalUser = Optional.ofNullable(user).map(User::getName);
System.out.println(optionalUser.get());// 输出 java
}
3.7 filter
接受一个Predicate来对Optional中包含的值进行过滤,如果包含中的值满足条件,那么还是返回这个Optional,否则就返回Optional.empty。
java
/**
* 如果存在一个值,并且该值与给定的值匹配,则返回秒速该值的Optional,否则返回一个空的Optional
*/
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
3.7.1 使用案例
java
public static void main(String[] args) {
User user = new User();
user.setName("java");
Optional<String> optionalUser = Optional.ofNullable(user).filter(o->o.getName().equals("java")).map(User::getName);
if(optionalUser.isPresent()){
System.out.println(optionalUser.get());// 输出 java
}else{
System.out.println("Optiaon为空");
}
}
3.8 or
or方法是只有在java11已上才有
如果一个Optional包含值,则返回自己,否则返回由参数supplier获得的Optional
java
/**
* 如果存在值时,返回一个Optional描述的值,否则将返回一个Optional产生通过供给的功能
* 参数:供应商-产生要返回的Optional的供应功能
* 返回值:如果一个值存在,返回一个Optional描述此值的Optional,否则Optional所生产的供应功能
* 抛出:NullpointerException如果提供函数的null或产生的null结果
*/
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
Objects.requireNonNull(supplier);
if (isPresent()) {
return this;
} else {
@SuppressWarnings("unchecked")
Optional<T> r = (Optional<T>) supplier.get();
return Objects.requireNonNull(r);
}
}
3.8.1 使用案例
java
public static void main(String[] args) {
User user = null;
Optional<User> optionalUser = Optional.ofNullable(user).or(() -> {
User user1 = new User();
user1.setName("java");
return Optional.of(user1);
});
if (optionalUser.isPresent()) {
System.out.println(optionalUser.get().getName()); //输出 java
} else {
System.out.println("为空");
}
}
3.9 stream
stream方法是只有在java11已上才有
将Optional转为一个Stream,如果Optional中包含值,那么就返回这个值的Stream,否则就返回一个空的Stream(Stream.empty())
java
/**
* 如果存在值,则返回仅包含该值的顺序Stream,否则返回一个空的Stream
* 返回值:Stream
*/
public Stream<T> stream() {
if (!isPresent()) {
return Stream.empty();
} else {
return Stream.of(value);
}
}
3.9.1 使用案例
java
public static void main(String[] args) {
User user = new User();
user.setName("java");
Stream<User> userStream = Optional.ofNullable(user).stream().filter(u->u.getName().equals("java"));
userStream.forEach(u->{
System.out.println(u.getName());
});
}