深刻理解 lambda表達式 與 Optional Null 源碼解析(Java11 三)

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * @author 陳楊
 */


@RunWith(SpringRunner.class)
@SpringBootTest
public class OptionalTest {


    @Test

    public void testOptional() {

1、Optional出現的原因

/*
 *   A container object which may or may not contain a non-{@code null} value.
 *
 *   一個裝泛型爲T的 值容器 能夠包含Null  以規避 空指針異常
 *   public final class Optional<T>
 */

2、深刻理解 Value-based Classes

/*
 *   Value-based Classes
 *
 *   https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html
 *
 *   final  immutable (但裏面能夠包含指向 可變對象的引用)
 *   具備equals、hashCode和toString的實現  僅從實例的狀態計算 而不是從其標識或任何其餘對象或變量的狀態計算
 *   不使用身份敏感的操做,例如實例之間的引用相等(==) 實例的hashCode,或實例的內部鎖(intrinsic lock)同步
 *   判斷是否相等 僅比較equals()方法  而非對象的引用(==)
 *   沒有可訪問的構造函數   經過工廠方法實例化,不保證明例建立的一致性(不必定是單例)
 *
 *   基於值的對象  沒有public的構造方法  比較值是否相等(不比較引用)
 */

3、Optional容器的構造

//    private static final Optional<?> EMPTY = new Optional<>();
//    private final T value;

//    Constructs an empty instance.
//    private Optional() { this.value = null; }


/*
 *    Constructs an instance with the described value.
 *
 *    private Optional(T value) {  this.value = Objects.requireNonNull(value); }
 */



/*
 *    Returns an empty {@code Optional} instance.  No value is present for this {@code Optional}.
 *
 *       public static<T> Optional<T> empty() {
 *           @SuppressWarnings("unchecked")
 *            Optional<T> t = (Optional<T>) EMPTY;
 *                 return t;
 *                 }
 */
Optional<List<String>> empty = Optional.empty();


/*    構造一個容器裏不爲 null 的容器對象
 *
 *    public static <T> Optional<T> of(T value) { return new Optional<>(value);  }
 */
Optional<List<String>> optional = Optional.of(Arrays.asList("Kirito", "Love", "Asuna"));


/*     構造一個容器裏可能爲 null 的容器對象
 *
 *     public static <T> Optional<T> ofNullable(T value) { return value == null ? empty() : of(value);  }
 */

4、普通方法

/*     獲取容器中的全部值
 *     public T get() {
 *          if (value == null) {
 *                throw new NoSuchElementException("No value present");
 *                             }
 *           return value;
 *           }
 */
System.out.println("---------------------------------------\n");
System.out.println("optional容器中存在的值:" + optional.get());


//     判斷 容器中存在值 返回true
//     public boolean isPresent() { return value != null; }
System.out.println("---------------------------------------\n");
System.out.println("optional容器中存在值:" + optional.isPresent());
System.out.println("empty容器中存在值:" + empty.isPresent());


//     判斷 容器中不存在值 返回true
//     @since   11
//     public boolean isEmpty() { return value == null; }
System.out.println("---------------------------------------\n");
System.out.println("optional容器中不存在值:" + optional.isEmpty());
System.out.println("empty容器中不存在值:" + empty.isEmpty());

5、高級拓展

一、ifPresent(Consumer)html

/*
 *     若是存在 value 對 value 進行一個 Consumer消費
 *     public void ifPresent(Consumer<? super T> action) {
 *                  if (value != null) {
 *                   action.accept(value);
 *                  }
 *      }
 *
 */
System.out.println("---------------------------------------\n");
System.out.println("optional容器中存在值就進行Consumer消費(打印輸出)");
optional.ifPresent(System.out::println);

二、ifPresentOrElse(Consumer)java

/*    若是存在 value 對 value 進行一個 Consumer消費  不存在 執行emptyAction(empty-based action)
 *    @since 9
 *    public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
 *             if (value != null) {
 *              action.accept(value);
 *             } else {
 *                emptyAction.run();
 *             }
 *    }
 */
System.out.println("---------------------------------------\n");
System.out.println("容器中存在值就打印值,不存在打印 hello world");
optional.ifPresentOrElse(System.out::println, () -> System.out.println("hello world"));
empty.ifPresentOrElse(System.out::println, () -> System.out.println("hello world"));

三、filter(Predicate)spring

/*
 *     若是存在value  且符合預期predicate 則對 value 進行預期操做predicate.test(value) 不然返回empty
 *     public Optional<T> filter(Predicate<? super T> predicate) {
 *                Objects.requireNonNull(predicate);
 *                if (!isPresent()) {
 *                  return this;
 *                } else {
 *                return predicate.test(value) ? this : empty();
 *                }
 *      }
 */
System.out.println("---------------------------------------\n");
System.out.println("遍歷集合元素");
optional.filter(strings -> {
    strings.forEach(System.out::println);
    return true;
});

四、or(Supplier)api

/*
 *      若是存在value 則返回value  不然使用supplier接口的get()方法 構造出一個Optional
 *      @since 9
 *      public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
 *             Objects.requireNonNull(supplier);
 *                if (isPresent()) {
 *                 return this;
 *                } else {
 *              @SuppressWarnings("unchecked")
 *                Optional<T> r = (Optional<T>) supplier.get();
 *                    return Objects.requireNonNull(r);
 *                }
 *        }
 */
System.out.println("---------------------------------------\n");
Supplier<Optional<List<String>>> sup =
        () -> Optional.ofNullable(Arrays.asList("Optional", "or", "supplier"));

System.out.println(empty.or(sup));

五、Stream.of(value)oracle

/*
 *      若是存在value 則返回Stream.of(value)  不然返回一個Stream.empty()
 *      @since 9
 *      public Stream<T> stream() {
 *             if (!isPresent()) {
 *             return Stream.empty();
 *              } else {
 *             return Stream.of(value);
 *             }
 *      }
 */
System.out.println("---------------------------------------\n");
System.out.println("以stream流 遍歷optional容器內的值");
Stream<List<String>> stream = Stream.of(optional.get());
stream.forEach(System.out::println);

六、orElse(T other)app

/*
 *      若是存在value 則返回value  不然返回T other
 *      public T orElse(T other) {
 *             return value != null ? value : other;
 *         }
 */
System.out.println("---------------------------------------\n");
System.out.println("  容器中存在值就返回值 不存在就返回{\"hello\",\"world\"}");
System.out.println(empty.orElse(Arrays.asList("hello", "world")));

七、orElseGet(Supplier)函數

/*
 *       若是存在value 則返回value  不然返回Supplier接口實現
 *       public T orElseGet(Supplier<? extends T> supplier) {
 *                return value != null ? value : supplier.get();
 *        }
 */
System.out.println("---------------------------------------\n");
Supplier<List<String>> listSupplier = () -> Arrays.asList("do", "orElseGet");
System.out.println(empty.orElseGet(listSupplier));

八、orElseThrow測試

/*
 *       若是存在value 則返回value  不然拋出異常NoSuchElementException
 *       @since 10
 *       public T orElseThrow() {
 *            if (value == null) {
 *             throw new NoSuchElementException("No value present");
 *              }
 *         return value;
 *        }
 */
System.out.println("---------------------------------------\n");
System.out.println("  容器中存在值就返回值 不存在就返回NoSuchElementException");

System.out.println(optional.orElseThrow());
try {
    System.out.println(empty.orElseThrow());
} catch (NoSuchElementException e) {
    System.out.println(" NoSuchElementException ---> No value present");
}

九、orElseThrow(Supplier)ui

/*
 *      若是存在value 則返回value  不然使用Supplier接口生成一個被拋出的exceptionSupplier -->exception
 *      public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
 *                        if (value != null) {
 *                             return value;
 *                            } else {
 *                    throw exceptionSupplier.get();
 *                        }
 *        }
 */
System.out.println("---------------------------------------\n");
Supplier<NoSuchElementException> noSuchElementException = NoSuchElementException::new;

try {
    System.out.println(empty.orElseThrow(noSuchElementException));
} catch (NoSuchElementException e) {
    System.out.println(" Supplier NoSuchElementException ---> No value present");
}

十、map(Function)this

/*
 *
 *      若是存在value 則返回value並做爲mapper的輸入 將其輸出做爲新的value存放至Optional  不然返回一個null的Optional
 *      若是通過mapper 後獲得的結果爲null  返回一個null的Optional
 *      mapper函數若爲null 則拋出NullPointerException
 *      map:對集合中每一個元素進行操做
 *
 *
 *      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));
 *                    }
 *       }
 */
System.out.println("---------------------------------------\n");
Function<List<String>, List<String>> function =
        up -> up.stream().map(String::toUpperCase).collect(Collectors.toList());
Optional<List<String>> o = optional.map(function);
System.out.println(o.get());

十一、flatMap(Function)

/*
         *      若是存在value 則返回value並做爲mapper的輸入 將其輸出做爲新的value存放至Optional  不然返回一個null的Optional
         *      若是通過mapper 後獲得的結果爲null  返回一個null的Optional
         *      mapper函數若爲null 則拋出NullPointerException
         *
         *      與map的方法的區別:
         *      map
         *
         *     return Optional.ofNullable(mapper.apply(value));
         *
         *      flatMap
         *
         *      Optional<U> r = (Optional<U>) mapper.apply(value);
         *      return Objects.requireNonNull(r);
         *      flatMap:對集合中每一個元素進行操做而後再扁平化
         *
         *
         *       public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
         *                     Objects.requireNonNull(mapper);
         *                             if (!isPresent()) {
         *                                 return empty();
         *                                } else {
         *                  @SuppressWarnings("unchecked")
         *                 Optional<U> r = (Optional<U>) mapper.apply(value);
         *                   return Objects.requireNonNull(r);
         *                             }
         *        }
         */
        System.out.println("---------------------------------------\n");
        Function<List<String>, Optional<List<String>>> func =
                up -> Optional.of(up.stream().map(String::toUpperCase).collect(Collectors.toList()));
        Optional<List<String>> u = optional.flatMap(func);
        System.out.println(u.get());

    }

}

6、測試

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-01 18:29:34.870  INFO 17140 --- [           main] com.java.design.java8.OptionalTest       : Starting OptionalTest on DESKTOP-87RMBG4 with PID 17140 (started by 46250 in E:\IdeaProjects\design)
2019-02-01 18:29:34.871  INFO 17140 --- [           main] com.java.design.java8.OptionalTest       : No active profile set, falling back to default profiles: default
2019-02-01 18:29:35.437  INFO 17140 --- [           main] com.java.design.java8.OptionalTest       : Started OptionalTest in 0.775 seconds (JVM running for 1.574)
---------------------------------------

optional容器中存在的值:[Kirito, Love, Asuna]
---------------------------------------

optional容器中存在值:true
empty容器中存在值:false
---------------------------------------

optional容器中不存在值:false
empty容器中不存在值:true
---------------------------------------

optional容器中存在值就進行Consumer消費(打印輸出)
[Kirito, Love, Asuna]
---------------------------------------

容器中存在值就打印值,不存在打印 hello world
[Kirito, Love, Asuna]
hello world
---------------------------------------

遍歷集合元素
Kirito
Love
Asuna
---------------------------------------

Optional[[Optional, or, supplier]]
---------------------------------------

以stream流 遍歷optional容器內的值
[Kirito, Love, Asuna]
---------------------------------------

  容器中存在值就返回值 不存在就返回{"hello","world"}
[hello, world]
---------------------------------------

[do, orElseGet]
---------------------------------------

  容器中存在值就返回值 不存在就返回NoSuchElementException
[Kirito, Love, Asuna]
 NoSuchElementException ---> No value present
---------------------------------------

 Supplier NoSuchElementException ---> No value present
---------------------------------------

[KIRITO, LOVE, ASUNA]
---------------------------------------

[KIRITO, LOVE, ASUNA]

Process finished with exit code 0
相關文章
相關標籤/搜索