Java基礎之Optional類(JDK1.8新特性)

定義

Optional是一個容器,它可以保存類型T的值,或者僅僅保存null,Optional類主要是用來避免空指針異常(NPE),其提供的一系列的方法配合Lambda表達式可以讓代碼更加清晰,語義化,以及避免了空指針異常的問題,這裏要注意是避免空指針異常,而不是避免返回null

Optional方法的使用

  1. empty 方法返回一個不包含值的Optional實例,注意不保證返回的empty是單例,不要用==比較。
public static<T> Optional<T> empty() 
  1. of 方法返回一個Optional實例,傳入的值必須是非空值,傳入null會拋出空指針異常。
public static <T> Optional<T> of(T value) 
  1. 返回一個Optional實例,如果傳入值非空,則實例中包含非空值,如果傳入null,返回不包含值的empty
    public static <T> Optional<T> ofNullable(T value)
  1. isPresent 方法用來判斷實例是否包含值,如果不包含非空值返回false,否則返回true
	public boolean isPresent();

  1. get方法,如果實例包含值則返回當前值,否則拋出NoSushElementException 異常.
	public T get();

不推薦調用上面兩個方法,因爲容易寫出如下代碼,比原先判斷if null的代碼還要髒

    public static String getUserName1(User user) {
        Optional<User> user1 = Optional.ofNullable(user);
        if (!user1.isPresent()) {
            return "參數爲空";
        }
        return user1.get().getName();
    }

下面是用if-null

  public static String getUserName(User user) {
        if (user == null) {
            return "參數爲空";
        }
        return user.getName();
    }
  1. ifPresent(Consumer consumer):如果option對象保存的值不是null,則調用consumer對象,否則不調用
		public void ifPresent(Consumer<? super T> consumer);

代碼示例:

	  Optional<Integer> optional1 = Optional.ofNullable(1);
        Optional<Object> optional2 = Optional.ofNullable(null);
     //如果不是null,調用Consumer
        optional1.ifPresent(t -> System.out.println("value is" + t));   //value is1
        //如果是null,不調用Consumer
        optional2.ifPresent(t -> System.out.println("value is " + t));   

如上代碼,輸出結果是 第一條 語句輸出value is1,第二條語句沒有輸出
7. filter方法如果值存在,並且這個值匹配給定的predicate,返回一個Optional用以描述這個值,否則返回一個空的Optional

Optional<T> filter(Predicate<? super <T> predicate)

代碼示例:

		Optional<Integer> optional1 = Optional.ofNullable(1);
       Optional<Object> optional2 = Optional.ofNullable(null);
       Optional<Integer> filter1 = optional1.filter(a -> a == null);
        Optional<Integer> filter2 = optional1.filter((a) -> a == 1);
        Optional<Object> filter3 = optional2.filter(a -> a == null);
		
	   System.out.println(filter1.isPresent()); //false
        System.out.println(filter2.isPresent()); //true
        System.out.println(filter2.get().intValue() == 1); //true
        System.out.println(filter3.isPresent()); //false

如上代碼,演示了filter方法如何使用,輸出結果如代碼註釋所示。
8. map(Function):對Optional中保存的值進行函數運算,並返回新的Optional(可以是任何類型)

	public<U> Optional<U> map(Function<? super T, ? extends U> mapper);

代碼示例:輸出結果已經寫在註釋中。

	 Optional<Integer> optional1 = Optional.ofNullable(1);
        Optional<Object> optional2 = Optional.ofNullable(null);
		Optional<String> str1Optional = optional1.map(a -> "key" + a);
        Optional<String> str2Optional = optional2.map(a -> "key" + a);
        System.out.println(str1Optional.get()); //key1
        System.out.println(str2Optional.isPresent()); //false
  1. flatMap():功能與map()相似,差別在返回值不同,flatMap方法的mapping函數返回值可以是任何類型T,而map方法的mapping函數必須是Optional
	public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper);

代碼示例:

		Optional<Integer> optional1 = Optional.ofNullable(1);
        Optional<Object> optional2 = Optional.ofNullable(null);
     	 Optional<Optional<String>> str11Optional = optional1.map(a -> Optional.of("key" + a));
        Optional<String> str22Optional = optional1.flatMap(a -> Optional.of("key" + a));
        System.out.println(str11Optional.get().get()); //key1
        System.out.println(str22Optional.get()); //key1
  1. orElse方法,如果optional對象保存的值不是null,則返回原來的值,否則返回value。
	public T orElse(T other);

代碼示例:

        Optional<Integer> optional1 = Optional.ofNullable(1);
        Optional<Object> optional2 = Optional.ofNullable(null);
	   System.out.println(optional1.orElse(1000) == 1); //true
        System.out.println((Integer) optional2.orElse(1000) == 1000);//true
  1. orElseGet(Supplier supplier):功能與orElse一樣,只不過orElseGet參數是一個對象。
	public T orElseGet(Supplier<? extends T> other);

代碼示例:

		     Optional<Integer> optional1 = Optional.ofNullable(1);
        Optional<Object> optional2 = Optional.ofNullable(null);
		 System.out.println(optional1.orElseGet(() -> 1000) == 1); //true
        System.out.println((Integer) optional2.orElseGet(() -> 1000) == 1000); //true

  1. orElseThrow方法,值不存在則調用傳入的Supplier參數,生成一個異常實例並拋出,這個方法通常與全局異常處理器一起使用,當參數或者其他情況獲取不到值是,拋出自定義異常,由異常處理器處理成通用返回結果。
	public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier);

代碼示例:

       optional1.orElseThrow(() -> {
            throw new IllegalStateException();
        });
        try {
            optional2.orElseThrow(() -> {
                throw new IllegalStateException();
            });
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }

實戰參考

假設我們要解析一段json字符串,按照傳統的if-null方式我們需要做如下處理:爲了獲取CUid的值,我們必須要判斷三次。

 public static String getOrgUid(String orgResult) {
        if (StringUtils.isBlank(orgResult)) {
            return null;
        }
        JSONObject jsonObject = JSON.parseObject(orgResult);
        if (jsonObject == null) {
            return null;
        }
        if ("success".equals(jsonObject.getString("result"))) {
            return jsonObject.getString("CUid");
        }
        return null;
    }

而運用了我們的Optional類之後,我們可以通過函數式變成來實現。

 public static String getNewUid(String orgResult) {
        String orElse = Optional.ofNullable(orgResult)
                .map(n -> JSONObject.parseObject(n))
                .map(a -> {
                    if ("success".equals(a.getString("result"))) {
                        return a.getString("CUid");
                    }
                    return null;
                }).orElse(null);
        return orElse;
    }

運用了函數式變成,我們只需要三段3段代碼就能輕鬆的駕馭,代碼簡潔明瞭。

總結

本文主要介紹了Optional類的一些常用方法,以及其應用場景,其主要是爲了規避空指針異常(NPE)。熟練的運用Optional類可以很大的簡化我們的代碼,使代碼簡潔明瞭。

參考

JDK8 Optional 應用場景與方式分析
Java 8 Optional 類
JDK8新特性:使用Optional

發佈了144 篇原創文章 · 獲贊 24 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章