Java8 之Optional 的使用
作为java8的新特性之一,可选在没有接触之前没有感受到过他的魅力,当真正的去用它才感觉到魅力之所在。可选,JAVA新增的工具类,主要是用来解决我们之前 NullPointException的问题。
我先贴一段之前的代码,部分截取,真实业务场景中所用到的代码。
if(bidId!= null){
//根据投标单ID,查询评标人ID --EmpId
List <SrmBidScore> srmBidScores = srmBidExamMapper.bidScoreByBid(bidId); //查询评分表信息
if(srmBidScores!= null){
for(SrmBidScore srmBidScore:srmBidScores){
Long empId = srmBidScore.getEmpId(); //获取评分表中的empId
if(empId!= null){
employeeList.add(employeeMapper.employeeBy(EMPID)); //根据评分表中的EMPID获取评分人信息
}
}
srmBidGroupListView.setEmployeeList(EmployeeList的); //将获取到的评分人,添加到评分小组信息中
}
}
我们发现,每涉及到一块逻辑判断都要保证前一步所使用的参数值不能是空,否者的话下面的方法就会报NullPointException 的问题。看着是逻辑特别乱,别人在看代码时候,也不便于阅读。
今天的主角Optional工具类就是教我们如何优雅的来解决这个问题;
一、创建Optional对象
直接上图,会发现有三个构造方法:ofNullable(T value),of(T value),empty()
三者区别:
of
创建一个非空Optional
ofNullable
/**
* 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);
}
empty
创建一个空的Optional对象。
所以说我们一般使用的话,就是直接使用ofNullable()来创建Optional对象实例。
二、Optional 方法
. get
获取Option对象中传入的值,如果对象有值返回Optional类型的值,如果传入值为空的话,会抛出 NoSuchElementException 异常;
User user = new User();
user.setName("Tom");
user.setAge("18");
Optional<User> OptionalUser = Optional.ofNullable(user);
System.out.println("-optional-ofNullable:" + OptionalUser.get());//-optional-of:User{name='Tom', age='18'}
Optional<User> OptionalUser = Optional.ofNullable(null);
System.out.println("-optional-ofNullable:" + OptionalUser.get());//Exception in thread "main" java.util.NoSuchElementException: No value present
源码
/**
* If a value is present in this {@code Optional}, returns the value,
* otherwise throws {@code NoSuchElementException}.
*
* @return the non-null value held by this {@code Optional}
* @throws NoSuchElementException if there is no value present
*
* @see Optional#isPresent()
*/
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");//如果传入值为空直接抛出异常
}
return value;
}
.map *
如果有值,则对其执行调用mapping函数得到返回值。如果传入值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional.
*map方法会将传入的lambda表达式的参数对原始的Optional值做修改;返回新的Optional实例作为map方法的返回值。
Optional<String> OptionalString = Optional.ofNullable("abc");
System.out.println(OptionalString.map((v) -> v.toUpperCase()));//Optional[ABC]
源码:public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();//如果传入的Optional对象为空,直接返回Optional空对象
else {
return Optional.ofNullable(mapper.apply(value));//如果不为空返回mapper函数得到返回值
}
}
.flatMap
如果有值返回mapper函数执行的Optional类型的值,没有值返回空Optional对象;
* flatMap方法与map方法类似,区别在于mapping函数的返回值不同。map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是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));
}
}
.filter
从字面理解应该是对Optional对象进行过滤;
通过传入lambda表达式件对Optional实例的值进行过滤。对于filter函数我们应该传入实现了Predicate接口的lambda表达式。如果满足则返回同一个Option实例,否则返回空Optional。
Optional<String> OptionalString = Optional.ofNullable("abc");
System.out.println(OptionalString.filter((v)->v.length()>4));//Optional.empty v的长度小于4,返回空的Optional对象
源码:
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
.ifPresent
如果Optional实例有值则为其调用consumer,否则不做处理; ifpersent方法接受lanbda表达式作为参数。
Optional<User> OptionalUser = Optional.ofNullable(user);
OptionalUser.ifPresent((value)->{
System.out.println(value.getName());});//Tom
源码:public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
.orElse
如果有值将值返回,没有值返回指定的值,这个好理解一点,只需要关注Optional实例对象是否有值就行。
Optional<String> OptionalString = Optional.ofNullable("abc");
System.out.println("orElse:"+OptionalString.orElse("def"));//有值得情况返回abc,如果我们构造对象时传入null,则返回def
源码:
public T orElse(T other) {
return value != null ? value : other;//很清楚
}
.orElseGet
orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。
Optional<String> OptionalString = Optional.ofNullable("abc");
System.out.println("orElseGet:"+ OptionalString.orElseGet(()-> "wasd"));//有值情况和orElse一样返回(abc),没有的话返回lambda表达式返回的‘wasd’
源码:
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
.orElseThrow
如果有值则将其返回,否则抛出supplier接口创建的异常;orElseThrow与orElse方法类似,返回默认值不同。
public class orElseThrowException extends Throwable{//异常类定义
orElseThrowException() {
super();
}
orElseThrowException(String msg) {
super(msg);
}
@Override
public String getMessage() {
return "orElseThrowException";
}
}
Optional<String> OptionalString = Optional.ofNullable(null);//这里我们在其构造对象时传入null
try{
OptionalString.orElseThrow(orElseThrowException::new);
}catch (Throwable e){
System.out.println("异常捕获");
System.out.println(e.getMessage());//打印orElseThrowException,自定义的异常
}
源码:public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
上一篇: java8——并行数据处理与性能
推荐阅读
-
android中优雅的处理nullPointException(java8 Optional)
-
Java8 之Optional 的使用
-
Java8中字符串处理库strman-java的使用示例
-
java8的LocalDateTime类使用
-
Java8中字符串处理库strman-java的使用示例
-
java IO流 之 输出流 OutputString()的使用
-
java IO流 之 输入流 InputString()的使用
-
Python笔记之time、datetime、calendar模块的使用!!!!
-
使用 Java8 实现观察者模式的方法(下)
-
java IO流 之 输入流 InputString()的使用