Java 8 新特性:6-Optional类

 先看看上面的说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
  * A container object which may or may not contain a non-null value.
  * If a value is present, {@code isPresent()} will return {@code true} and
  * {@code get()} will return the value.
  *Optional是一个容器对象,它可能包含,也可能不包含一个非空的值,如果这个值存在,isPresent方法将返回true,get方法将会返回它本身
  * <p>Additional methods that depend on the presence or absence of a contained
  * value are provided, such as {@link #orElse(java.lang.Object) orElse()}
  * (return a default value if value not present) and
  * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
  * of code if the value is present).
  *Optional提供一些额外的方法,这些方法依赖于它所包含的对象存在与否,例如orElse如果这个包含的对象不存在,将会返回一个默认值和ifPresent方法,如果包含的值存在,则会执行方法块中的内容
  * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
  * class; use of identity-sensitive operations (including reference equality
  * ({@code ==}),  hash code, or synchronization) on instances of
  * {@code Optional} may have unpredictable results and should be avoided.
  *这是一个基于值的class类,对于同一性(特性)敏感的操作 (包含引用的相等性如:==),同一性的hashcode或者同步等等、对optional实例可能会产生不可预料的结果,这种结果应该被避免。
  * @since 1.8
  */

  

再看看该类:
public final class Optional<T> 
这里一个final类
这是一个基于值的类,上面给出了什么叫基于值,上面给出的链接地址不全,看这里:
http://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html

 

这里说的是基于值的类需要满足以下几点:
1、 final类型和不可变的(可能会包含可变对象的引用)
2、 有equals、hashCode、toString方法的实现,它是通过实例的状态计算出来的,而并不会通过其它的对象或变量去计算。 
3、 不会使用身份敏感的操作,比如在二个实例之间引用相等性、hashCode或者内在的锁。
4、 判断二个值相等仅仅通过equal方法,而不会通过==去判断。
5、 它不提供构造方法,它通过工厂方法创建它的实例,这不保证返回实例的一致性。
6、 当它们相等时,它是可以自由替换的。如果x和y 调用equal方法返回true,那么可以将x和y任意交换,它的结果不会产生任何变化。

然后再回来看Optional,你能看到它是私有的:

1
2
3
private  Optional() {
     this .value =  null ;
}

 

 

 

在它的所有方法中,如果要创建Optional对象,先看看它常用的三个方法。
empty方法回一个空的 Optional对象。
of方法接收一个T参数,T必需为非null值,返回一个Optional对象。
ofNullable方法接收一个T参数,如果T为null,它会调用empty方法,如果不为null则调用of方法。

再看看这二个方法:
isPresent: 如果这个对象的值不为null返回true,否则返回false。
get:如果这个值存在,则返回这个值,如果这个值为null,则抛出异常。
在使用中,这二个方法基本是成对出现的,下面来看一个例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String str =  "hello" ;
Optional<String> strValue = Optional.of(str);
 
System.out.println( "part1-------------------" );
 
if (str !=  null ){
    System.out.println(str);
}
 
System.out.println( "part2-------------------" );
 
if (strValue.isPresent()){
    System.out.println(strValue.get());
}

这里,part1和part2的代码是等价的,Optional还提供了一种更简单的方法
strValue.ifPresent(s -> System.out.println(s));
ifPresent方法接收一个consumer函数式接口(之前介绍过),将自己的非空的逻辑写进去。Optioanal该方法更加简洁。

orElse方法:接收一个参数,如果存在,返回这个值本身,否则返回返回这个参数。
orElseGet方法:接收一个Supplier,如果存在,返回这个值本身,否则返回Supplier
对象。

map方法:接收一个Function,如果Optioanal为null则抛出异常(所以这里创建Optional对象时建议用Optional.ofNullable()),如果为空值则返回空,如果不为空则返回Function的返回值。
(例如:一个对象Obj,有一个List属性,如果List有值,返回List,否则返回空集合,可以这么写(

1
2
3
Parent parent =  new  Parent();
Optional<Parent> parentVal = Optional.ofNullable(parent);
System.out.println(parentVal.map(m -> m.getList()).orElse(Collections.emptyList()));

Optioanal通常作为方法的返回值来使用,它可以有效的规避返回null的结果,如果一个类需要序列化,当Optional作为参数类型或是成员变量类型是有问题的。因为Optional没有实现序列化,所以Optioanl通常不被建议作为参数或常量使用。

下面给出一些Optional常用的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package  com.demo.jdk8;
 
import  java.util.Collections;
import  java.util.List;
import  java.util.Optional;
 
public  class  Test6 {
    public  static  void  main(String[] args) {
       String str =  "hello" ;
       Optional<String> strValue = Optional.of(str);
 
       System.out.println( "part1-------------------" );
 
       if (str !=  null ){
          System.out.println(str);
       }
 
       System.out.println( "part2-------------------" );
 
       if (strValue.isPresent()){
          System.out.println(strValue.get());
       }
 
       System.out.println( "part3-------------------" );
 
       strValue.ifPresent(s -> System.out.println(s));
 
       System.out.println( "part4-------------------" );
       Optional<String> op = Optional.ofNullable( null );
 
       System.out.println(op.orElse( "hahahaha" ));
       System.out.println( "part5-------------------" );
       Optional<String> opt = Optional.ofNullable( "nihao" );
 
       System.out.println(op.orElseGet(() ->  "hehehe" ));
       System.out.println( "part6-------------------" );
       System.out.println(opt.map(m -> m +  "123" ).orElseGet(() ->  "world" ));
 
         System.out.println( "part7-------------------" );
 
         Parent parent =  new  Parent();
//        List<Object> list = Arrays.asList("张三","李四");
//        parent.setList(list);
 
         Optional<Parent> parentVal = Optional.ofNullable(parent);
         System.out.println(parentVal.map(m -> m.getList()).orElse(Collections.emptyList()));
 
     }
 
     public  void  test(Optional optional){
 
     }
 
}
 
class  Parent{
     private  List<Object> list;
 
     public  List<Object> getList() {
         return  list;
     }
 
     public  void  setList(List<Object> list) {
         this .list = list;
     }
}

  

 例子请看这里:https://github.com/LeeScofield/java8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值