java中Optional的使⽤详细解析
⽬录
Optional的使⽤详解
2、构建Optional
3、Optional API 及源码注解
4、测试使⽤
4.1、构建
4.2、判断类
4.3、获取类(常⽤)
4.4、转换类
4.5、测试API使⽤
Optional的使⽤详解
1、Optional介绍
Optional 类是⼀个可以为null的容器对象。如果值存在则isPresent()⽅法会返回true,调⽤get()⽅法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有⽤的⽅法,这样我们就不⽤显式进⾏空值检测。
Optional 类的引⼊很好的解决空指针异常。
2、构建Optional
构建⼀个Optional对象;⽅法有:empty( )、of( )、ofNullable( )
//返回⼀个描述给定值的Optional ,如果不为null ,则返回⼀个空的Optional 。
//参数:值–描述的可能为null值
//类型参数:<T> –值的类型
//返回值:⼀个Optional与如果指定值是⾮当前值null ,否则⼀个空Optional
Optional.ofNullable("");
//返回⼀个Optional描述给定的⾮null值。
//参数:value –要描述的值,必须为⾮null
//类型参数:<T> –值的类型
//返回值:存在值的Optional
Optional.of("");
//返回⼀个空的Optional实例。此Optional没有值。
//类型参数:<T> –不存在的值的类型
//返回值:⼀个空的Optional
//api注意:尽管这样做可能很诱⼈,但应通过将==与pty()返回的实例进⾏⽐较来避免测试对象是否为空。
// 不能保证它是⼀个单例。
// ⽽是使⽤isPresent()
3、Optional API 及源码注解
package java.util;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
⼀个可能包含也可能不包含⾮null值的容器对象。如果存在值,则isPresent()返回true 。如果不存在任何值,则该对象被视为空,并且isPresent()返回false 。提供了其他取决于所包含值是否存在的⽅法,例如orElse() (如果不存在值,则返回默认值)和ifPresent() (如果存在值,则执⾏操作)。
这是⼀个基于值的类;在Optional实例上使⽤标识敏感的操作(包括引⽤等于( == ),标识哈希码或同步)可能会产⽣不可预测的结果,应避免使⽤
*/
public final class Optional<T> {
/**
* empty()通⽤实例
*/
private static final Optional<?> EMPTY = new Optional<>();
/**
* 如果不为空,则为该值;否则为false。如果为null,则表⽰不存在任何值
*/
private final T value;
/**
构造⼀个空实例。
impl注意:
通常,每个VM仅应存在⼀个空实例EMPTY
*/
private Optional() {
this.value = null;
}
/**
返回⼀个空的Optional实例。此Optional没有值。
类型参数:<T> –不存在的值的类型
返回值:⼀个空的Optional
api注意:
尽管这样做可能很诱⼈,但应通过将==与pty()返回的实例进⾏⽐较来避免测试对象是否为空。不能保证它是⼀个单例。⽽是使⽤isPresent()      */
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
/**
使⽤描述的值构造⼀个实例。
参数:值–要描述的⾮null值
抛出:NullPointerException如果值为null
*/
private Optional(T value) {
this.value = quireNonNull(value);
}
/**
返回⼀个Optional描述给定的⾮null值。
参数:value –要描述的值,必须为⾮null
类型参数:<T> –值的类型
返回值:存在值的Optiona
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
/**
返回⼀个描述给定值的Optional ,如果不为null ,则返回⼀个空的Optional 。
参数:值–描述的可能为null值
类型参数:<T> –值的类型
返回值:⼀个Optional与如果指定值是⾮当前值null ,否则⼀个空Optional
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
/
**
如果存在值,则返回该值,否则抛出NoSuchElementException 。
返回值:此Optional描述的⾮null值
抛出:NoSuchElementException如果不存在任何值
api注意:此⽅法的⾸选替代⽅法是orElseThrow() 。
*/
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
/**
如果存在值,则返回true ,否则返回false 。
返回值:如果存在值,则为true ,否则为false
*/
public boolean isPresent() {
return value != null;
}
/**
如果不存在值,则返回true ,否则返回false 。
返回值:如果不存在值,则为true ,否则为false
*/
public boolean isEmpty() {
return value == null;
}
/**
如果存在值,则使⽤该值执⾏给定的操作,否则不执⾏任何操作。
参数:动作–要执⾏的动作(如果存在值)
*/
public void ifPresent(Consumer<? super T> action) {
if (value != null) {
action.accept(value);
}
}
/**
如果存在值,则使⽤该值执⾏给定的操作,否则执⾏给定的基于空的操作。
参数:动作–要执⾏的动作(如果存在值)emptyAction –要执⾏的基于空的操作(如果不存在任何值)
抛出:NullPointerException如果存在⼀个值并且给定的操作为null ,或者不存在任何值并且给定的基于空的操作为null
@since 9
*/
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
if (value != null) {
action.accept(value);
} else {
emptyAction.run();
}
}
/**
如果存在⼀个值,并且该值与给定的谓词匹配,则返回描述该值的Optional ,否则返回⼀个空的Optional 。
参数:谓词–应⽤于值的谓词(如果存在)
返回值:⼀个Optional描述此的值Optional ,如果⼀个值存在并且该值给定的谓词相匹配,否则⼀个空Optional
抛出:NullPointerException如果谓词为null
*/
public Optional<T> filter(Predicate<? super T> predicate) {
if (!isPresent()) {
return this;
} else {
st(value) ? this : empty();
}
}
/**
如果存在值,则返回⼀个Optional描述(就像by ofNullable ),将给定映射函数应⽤于该值的结果,否则返回⼀个空的Optional 。
如果映射函数返回null结果,则此⽅法返回空的Optional
*/
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
if (!isPresent()) {
return empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
/**
如果存在⼀个值,则返回将给定Optional -bearing映射函数应⽤于该值的结果,否则返回⼀个空的Optional 。
此⽅法类似于map(Function) ,但是映射函数是其结果已经是Optional函数,如果调⽤该函数,则flatMap不会将其包装在其他Optional 。
参数:mapper –应⽤于值的映射函数(如果存在)
类型参数:<U> –映射函数返回的Optional值的类型
返回值:施加的结果Optional荷瘤映射函数此的值Optional ,如果⼀个值存在,否则⼀个空Optional
抛出:NullPointerException如果映射函数为null或返回null结果
*/
public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
if (!isPresent()) {
return empty();
} else {
@SuppressWarnings("unchecked")
Optional<U> r = (Optional<U>) mapper.apply(value);
quireNonNull(r);
}
}
/**
如果值存在时,返回⼀个Optional描述的值,否则将返回⼀个Optional产⽣通过供给功能。
参数:供应商–产⽣要返回的Optional的供应功能
返回值:返回⼀个Optional描述此的值Optional ,如果⼀个值存在,否则Optional所⽣产的供应功能。
抛出:NullPointerException如果提供的函数为null或产⽣null结果
* @since 9
*/
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
if (isPresent()) {
return this;
} else {
@SuppressWarnings("unchecked")
Optional<T> r = (Optional<T>) ();
quireNonNull(r);
}
}
/
**
如果存在值,则返回仅包含该值的顺序Stream ,否则返回空Stream 。
返回值:作为Stream的可选值
* @since 9
*/
public Stream<T> stream() {
if (!isPresent()) {
pty();
} else {
return Stream.of(value);
}
}
/**
如果存在值,则返回该值,否则返回other 。
参数:其他–要返回的值(如果不存在任何值)。可以为null 。
返回值:值(如果存在),否则other
*/
public T orElse(T other) {
return value != null ? value : other;
}
/**
如果存在值,则返回该值,否则返回由供应函数产⽣的结果。
参数:供应商–产⽣要返回的值的供应函数
返回值:值(如果存在),否则提供功能产⽣的结果
*/
public T orElseGet(Supplier<? extends T> supplier) {
return value != null ? value : ();
}
/**
* If a value is present, returns the value, otherwise throws
* {@code NoSuchElementException}.
*
* @return the non-{@code null} value described by this {@code Optional}
* @throws NoSuchElementException if no value is present
* @since 10
*/
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
/**
如果存在值,则返回该值,否则抛出由异常提供函数产⽣的异常。
参数:exceptionSupplier –产⽣要抛出的异常的提供函数
类型参数:<X> –引发的异常类型
返回值:值(如果存在)
抛出:X –如果不存在任何值NullPointerException如果不存在任何值并且异常提供函数为null
api注意:带有空参数列表的对异常构造函数的⽅法引⽤可⽤作提供者
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {        if (value != null) {
return value;
} else {
();
}
}
}
4、测试使⽤
4.1、构建
//返回⼀个描述给定值的Optional ,如果不为null ,则返回⼀个空的Optional 。
//参数:值–描述的可能为null值
//类型参数:<T> –值的类型
//返回值:⼀个Optional与如果指定值是⾮当前值null ,否则⼀个空Optional
Optional s1 = Optional.ofNullable(null);
// 构建⼀个value不可以为null的optional对象,如果of()的⼊参为null会报空指针异常;
Optional<MyUser> s2 = Optional.of(new MyUser("阿辉2","123456"));
/
/ 构建⼀个value可以为null的optional对象;
Optional<MyUser> s3 = Optional.ofNullable(null);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
/* 输出
* pty
* Optional[MyUser{id='阿辉2', username='123456'}]
* pty
**/
4.2、判断类
Optional<MyUser> myUser1 = pty();
Optional<MyUser> myUser2 = Optional.of(new MyUser("阿飞", "123456"));
// filter传⼊⼀个lambda,lambda返回值为boolean;true:不做任何改变,false:返回⼀个空的optional;
Optional<MyUser> myUser3 = myUser2.filter(user -> "错误的密码".Username()));
// isPresent就是判断value是不是null;我们在调⽤get之前,⼀定要先调⽤isPresent,因为直接如果value是null,直接调⽤get会报异常;
if (myUser1.isPresent()) {
MyUser value = ();
System.out.println("optional value:" + value);
} else {
System.out.println("optional value==null");
}
// ifPresent传⼊⼀段lambda,当value!=null时,执⾏⾥⾯的逻辑;当当value==null时,啥都不⼲;
myUser2.ifPresent(value -> System.out.println("optional value:" + value));
System.out.println(myUser3);
// 输⼊如下:
//optional value==null
//optional value:MyUser{id='阿飞', username='123456'}
//pty
4.3、获取类(常⽤)
Optional<MyUser> userInfoEmptyOpt = pty();
Optional<MyUser> userInfoOpt = Optional.of(new MyUser("阿飞","123456"));
/
/ 1、直接获取,注意如果value==null,会报NoSuchElementException异常
MyUser userInfo1 = ();
// 2、orElse可以传⼊⼀个UserInfo类型的对象作为默认值;
//    当value!=null时,返回value值;当value==null时,返回默认值作为代替;
MyUser userInfo2 = Else(new MyUser("阿飞1","123456"));
// 3、orElseGet和orElse不同的是orElseGet可以传⼊⼀段lambda表达式;
// 当value!=null时,返回value值;
// 当value==null时,使⽤该lambda返回的对象作为默认值;
MyUser userInfo3 = ElseGet(() -> new MyUser("阿飞2","123456"));
// 4、orElseThrow可以传⼊⼀段lambda表达式,lambda返回⼀个Exception;当value!=null时,返回value值;当value==null时,抛出该异常;        MyUser userInfo4 = ElseThrow(NullPointerException::new);
System.out.println(userInfo1);
System.out.println(userInfo2);
System.out.println(userInfo3);
System.out.println(userInfo4);
// 输出如下:
// UserInfo(username=阿飞, password=123456)
// UserInfo(username=阿飞1, password=123456)
// UserInfo(username=阿飞2, password=123456)
// UserInfo(username=阿飞, password=123456)
4.4、转换类
Optional<MyUser> userInfoOpt = Optional.of(new MyUser("阿飞","123456"));
/
/ 原来value的类型是UserInfo,经过map转换为Optional<String>
Optional<String> username = userInfoOpt.map(MyUser::getId);
// 当map的⼊参也是⼀个Optional时,经过map转化后会形成Optional<Optional<String>>这种嵌套结构;但flatMap可以把这种嵌套结构打平;        Optional<Optional<String>> unFlatMap = userInfoOpt.map(user -> Optional.Id()));
Optional<String> flatMap = userInfoOpt.flatMap(user -> Optional.Id()));
System.out.println(username);
System.out.println(unFlatMap);
System.out.println(flatMap);
// 输出如下:
// Optional[阿飞]
// Optional[Optional[阿飞]]
// Optional[阿飞]
4.5、测试API使⽤
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Optional;
/**
springboot实现aop* @version 1.0
* @author: crush
* @date: 2021-04-12 20:51

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。