Java 8 Optional正确使用

義往昔 9天前 ⋅ 19 阅读

 optional: 可以帮我们把判空的代码写得更优雅

原来解决方案: 我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数。这正是一些类似Guava的外部API试图解决的问题。

 一些JVM编程语言比如Scala、Ceylon等已经将对在核心API中解决了这个问题。

  1. 构造 

//调用工厂方法创建Optional实例
Optional name = Optional.of("Sanaulla");
//传入参数为null,抛出NullPointerException.
Optional someNull = Optional.of(null);

为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。

Optional empty = Optional.ofNullable(null);

https://blog.csdn.net/boling_cavalry/article/details/77610629

 

if (name.isPresent()) {
  //在Optional实例内调用get()返回已存在的值
  System.out.println(name.get());//输出Sanaulla
}
这种写法就是不优雅的,跟原先判断 !=null 啥区别

optional意义:

  • 用在函数上,让调用者必须去判断空否
  • 用在空对象处理上, 但结合着lambda用

 

ifPresent   和 orElse  orElseGet  orElseThrow

如果Optional实例有值则为其调用consumer,否则不做处理.

要理解ifPresent方法,首先需要了解Consumer类。简答地说,Consumer类包含一个抽象方法。该抽象方法对传入的值进行处理,但没有返回值。

Java8支持不用接口直接通过lambda表达式传入参数。

如果Optional实例有值,调用ifPresent()可以接受接口段或lambda表达式。类似下面的代码:

//ifPresent方法接受lambda表达式作为参数。
//lambda表达式对Optional的值调用consumer进行处理。
name.ifPresent((value) -> {
  System.out.println("The length of the value is: " + value.length());
return “adf”;//此处不可以有返回值
});

System.out.println(empty.orElse("There is no value present!"));

orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。示例如下:

System.out.println(empty.orElseGet(() -> "Default Value"));

在orElseGet方法中,我们传入一个Supplier接口。然而,在orElseThrow中我们可以传入一个lambda表达式或方法,如果值不存在来抛出异常。示例如下:

empty.orElseThrow(ValueAbsentException::new);



 

map flatmap

如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。

map方法用来对Optional实例的值执行一系列操作。通过一组实现了Function接口的lambda表达式传入操作。map方法示例如下:

//map方法执行传入的lambda表达式参数对Optional实例的值进行修改。
//为lambda表达式的返回值创建新的Optional实例作为map方法的返回值。
Optional upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found"));
    Optional any = getAutoUsedGoodsSkill(effect);
        return any.map(u->Float.parseFloat(u.getMsg()))
                .orElse(0F);

//        if (any.isPresent()) {
//            return Float.parseFloat(any.get().getMsg());
//        }
//        return 0;

 

flatmap 如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。flatMap与map(Funtion)方法类似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装。

//flatMap与map(Function)非常类似,区别在于传入方法的lambda表达式的返回类型。
//map方法中的lambda表达式返回值可以是任意类型,在map函数返回之前会包装为Optional。 
//但flatMap方法中的lambda表达式返回值必须是Optionl实例。 
upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(upperName.orElse("No value found"));//输出SANAULLA

 

filter

Optional<String> anotherName = Optional.of("Sana");
Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);
//输出:name长度不足6字符
System.out.println(shortName.orElse("The name is less than 6 characters"));

 

public String getStudentUpperName(int id){
    Optional<Student> optional = Optional.ofNullable(queryById(id));

    return optional.map(student -> student.getName())
                   .map(name -> name.toUpperCase())
                   .orElse("invalid");
}

public Student getStudent(int id){
    Optional<Student> optional = Optional.ofNullable(queryById(id));

    //如果为空就返回DEFAULT对象
    return optional.orElseGet(() -> getDefault());
}


注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: