1. 程式人生 > >Java 8 新特性:4-Optional類

Java 8 新特性:4-Optional類

get方法 syn 序列 new ret 有一個 例子 使用 n)

(原)

先看看上面的說明:

/**
 * 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,你能看到它是私有的:

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,則拋出異常。


在使用中,這二個方法基本是成對出現的,下面來看一個例子。

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,否則返回空集合,可以這麽寫(

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常用的例子:

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

Java 8 新特性:4-Optional類