JDK8新特性-Optional類

Supplier 接口

  • JDK8 新增函數是接口
  • 提供一個get方法, 不接收參數, 返回一個參數
    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();

Optional

概述

  • JDK8 新增, 主要用於解決 NullPointException異常
  • 私有構造方法, 不允許通過new 獲得一個Optional實例
  • 提供一系列靜態工廠方法獲得Optional對象
  • value爲空的Optional可以認爲是一個空的Optional

API 簡介

empty 方法

 
    private static final Optional<?> EMPTY = new Optional<>();
	/*
     * 返回一個空的Optional實例, 這裏的空是指value不存在
     */
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

of 方法

    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

	/**
     * 返回一個Optional對象, Optional對象的value值爲傳入的value
     * 如果傳入的value爲null, 則會拋NullPointException異常
     */
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

ofNullable 方法

    /**
     * 返回一個Optional對象, Optional對象的value爲傳入的value
     * 如果傳入的value爲空, 則返回一個空的Optional對象
     * otherwise returns an empty {@code Optional}.
     */
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

get 方法

    /**
     * 如果當前Optional的value存在的話, 就返回value
     * 如果value爲null,就拋出NoSuchElementException異常
     *
     * @see Optional#isPresent()
     */
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

isPresent 方法

    /**
     * 判斷當前Optional的value是否存在, 存在就返回true
     * 如果當前Optional的value爲null則返回false
     * @return {@code true} if there is a value present, otherwise {@code false}
     */
    public boolean isPresent() {
        return value != null;
    }

ifPresent 方法

    /**
     * 接收一個函數式接口Consumer用於處理操作
     * 如果value存在(不爲null), 則調用傳入的Consumer的accept方法進行處理
     * 如果value不存在(爲null), 則什麼事都不做
     * 如果傳入的Consumer爲空的話, 則會拋出NullPointerException異常
     */
    public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

filter 方法

    /**
     * 接收一個函數式接口Predicate進行條件匹配
     * 如果傳入的predicate爲空或predicate匹配失敗, 則返回一個空的Optional(value爲null)
     * 如果傳入的predicate匹配成功, 則返回當前的Optional
     */
    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }

map 方法

    /**
     * 接收一個函數式接口Function類型的參數對當前的Optional進行一些處理以及類型轉換
     * 如果傳入的Function類型參數爲空, 就拋出NullPointException異常
     * 如果當前的Optional是一個空的Optional, 就返回一個空的Optional(value爲空)
	 * 如果Function接口的apply方法執行之後, 返回的結果爲null, 同樣返回一個空的Optional
     * 當前的Optional中value類型爲T, 傳入的Function類型爲Function<T, U>
     * 返回的新的Optional中value類型爲U
     */
    public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }

flatMap 方法

    /**
     * 和map方法功能類似, 但是有一些區別, map方法是將T轉換成U之後, 再使用Optional.ofNullable方法
     * 獲取Optional<U>類型的Optional, flatMap是function的函數完成對T的處理之後, 直接返回一個
     * Optional<U>類型的Optional, 所以如果Function的apply方法返回爲空
     * 則會拋出NullPointerException異常
     */
    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));
        }
    }

orElse 方法

    /**
     * 如果當前Optional的value存在, 就返回這個value
     * 如果當前Optional的value不存在, 就返回傳入的值other
     */
    public T orElse(T other) {
        return value != null ? value : other;
    }

orElseGet 方法

    /**
     * 方法接收一個Supplier<? extends T>參數
     * 如果當前Optional的value存在, 就返回這個value
     * 如果當前Optional的value不存在,則調用other的get方法生成一個
     * 如果other爲空, 則拋出NullPointerException異常
     */
    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }

API 用法舉例

    public static void main(String[] args) {
        // 1. empty 方法
        Optional<String> optional = Optional.empty();
        // 拋出NoSuchElementException
//        System.out.println(optional.get());

        // 2. of 方法 & get方法
        optional = Optional.of("七夜雪");
        System.out.println("2 ---> " + optional.get());

        // 3. isPresent方法
        if (optional.isPresent()) {
            System.out.println("3 ---> " + optional.get());
        }

        // 4. ifPresent, 測試案例3中這種判斷方式和現有的先判斷是否爲null, 再處理是一致的, 更好的一種方式是使用ifPresent
        optional.ifPresent(item -> System.out.println("4 ---> " + item));
        optional = Optional.empty();
        // 這一行因爲optional爲空, 所以不會執行輸出
        optional.ifPresent(item -> System.out.println("4 ---> " + item));

        // 5. filter方法
        optional = Optional.of("七夜雪").filter(item -> "七夜".equals(item));
        System.out.println("5 --->" + optional.isPresent());
        optional = Optional.of("七夜雪").filter(item -> "七夜雪".equals(item));
        System.out.println("5 --->" + optional.isPresent() + ", value : " + optional.get());

        // 6. map 方法
        Optional<Integer> optional1 = Optional.of(1);
        optional = optional1.map(item -> "七夜雪-> " + item);
        System.out.println("6 ---> " + optional.get());
        optional = optional1.map(item -> null);
        System.out.println("6 ---> " + optional.isPresent());
        optional1 = Optional.empty();
        optional = optional1.map(item -> "七夜雪-> " + item);
        System.out.println("6 ---> " + optional.isPresent());

        // 7. flatMap 方法
        optional1 = Optional.of(1);
        optional = optional1.flatMap(item -> Optional.of("七夜雪-> " + item));
        System.out.println("7 ---> " + optional.get());

        // 8. orElse方法
        System.out.println("8 --->" + optional.get());
        optional = Optional.empty();
        System.out.println("8 --->" + optional.orElse("碧落"));

        // 9. orElseGet 方法
        System.out.println("9 --->" + optional.orElseGet(() -> "紅塵"));
        optional = Optional.of("七夜雪");
        System.out.println("9 --->" + optional.orElseGet(() -> "紅塵"));

        // 10. ofNullable 方法
        optional = Optional.ofNullable(null);
        System.out.println("10 --->" + optional.isPresent());
        optional = Optional.ofNullable("七夜雪");
        System.out.println("10 --->" + optional.isPresent());
    }

輸出 :

1 --->false
2 ---> 七夜雪
3 ---> 七夜雪
4 ---> 七夜雪
5 ---> false
5 ---> true, value : 七夜雪
6 ---> 七夜雪-> 1
6 ---> false
6 ---> false
7 ---> 七夜雪-> 1
8 --->七夜雪-> 1
8 ---> 碧落
9 ---> 紅塵
9 ---> 七夜雪
10 --->false
10 ---> true
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章