Java語法進階16-Lambda-Stream-Optional

Lambda

  大年初二,大門不出二門不邁。繼續學習!

函數式接口

  Lambda表達式其實就是實現SAM接口的語法糖,所謂SAM接口就是Single Abstract Method,即該接口中只有一個抽象方法須要實現,固然該接口能夠包含其餘非抽象方法。編程

   它關注方法具有什麼樣的功能,強調作什麼,而不是以什麼形式作數組

  • 面向對象的思想:安全

    • 作一件事情,找一個能解決這個事情的對象,調用對象的方法,完成事情.app

  • 函數式編程思想:ide

    • 只要能獲取到結果,誰去作的,怎麼作的都不重要,重視的是結果,不重視過程函數式編程

自定義函數式接口

   只要確保接口中有且僅有一個抽象方法便可函數

修飾符 interface 接口名稱 {
    public abstract 返回值類型 方法名稱(可選參數信息);// public abstract 是能夠省略的
    // 其餘非抽象方法內容
}

消費型接口

  消費型接口的抽象方法特色:有形參,可是返回值類型是void學習

接口名 抽象方法 描述
Consumer<T> void accept(T t) 接收一個對象用於完成功能
BiConsumer<T,U> void accept(T t, U u) 接收兩個對象用於完成功能
DoubleConsumer void accept(double value) 接收一個double值
IntConsumer void accept(int value) 接收一個int值
LongConsumer void accept(long value) 接收一個long值
ObjDoubleConsumer<T> void accept(T t, double value) 接收一個對象和一個double值
ObjIntConsumer<T> void accept(T t, int value) 接收一個對象和一個int值
ObjLongConsumer<T> void accept(T t, long value) 接收一個對象和一個long值

供給型接口

  供給型接口的抽象方法特色:無參,可是有返回值優化

接口名 抽象方法 描述
Supplier<T> T get() 返回一個對象
BooleanSupplier boolean getAsBoolean() 返回一個boolean值
DoubleSupplier double getAsDouble() 返回一個double值
IntSupplier int getAsInt() 返回一個int值
LongSupplier long getAsLong() 返回一個long值

判斷型接口

  判斷型接口的抽象方法特色:有參,可是返回值類型是boolean結果spa

接口名 抽象方法 描述
Predicate<T> boolean test(T t) 接收一個對象
BiPredicate<T,U> boolean test(T t, U u) 接收兩個對象
DoublePredicate boolean test(double value) 接收一個double值
IntPredicate boolean test(int value) 接收一個int值
LongPredicate boolean test(long value) 接收一個long值

功能型接口

  功能型接口的抽象方法特色:既有參數又有返回值

接口名 抽象方法 描述
Function<T,R> R apply(T t) 接收一個T類型對象,返回一個R類型對象結果
UnaryOperator<T> T apply(T t) 接收一個T類型對象,返回一個T類型對象結果
DoubleFunction<R> R apply(double value) 接收一個double值,返回一個R類型對象
IntFunction<R> R apply(int value) 接收一個int值,返回一個R類型對象
LongFunction<R> R apply(long value) 接收一個long值,返回一個R類型對象
ToDoubleFunction<T> double applyAsDouble(T value) 接收一個T類型對象,返回一個double
ToIntFunction<T> int applyAsInt(T value) 接收一個T類型對象,返回一個int
ToLongFunction<T> long applyAsLong(T value) 接收一個T類型對象,返回一個long
DoubleToIntFunction int applyAsInt(double value) 接收一個double值,返回一個int結果
DoubleToLongFunction long applyAsLong(double value) 接收一個double值,返回一個long結果
IntToDoubleFunction double applyAsDouble(int value) 接收一個int值,返回一個double結果
IntToLongFunction long applyAsLong(int value) 接收一個int值,返回一個long結果
LongToDoubleFunction double applyAsDouble(long value) 接收一個long值,返回一個double結果
LongToIntFunction int applyAsInt(long value) 接收一個long值,返回一個int結果
DoubleUnaryOperator double applyAsDouble(double operand) 接收一個double值,返回一個double
IntUnaryOperator int applyAsInt(int operand) 接收一個int值,返回一個int結果
LongUnaryOperator long applyAsLong(long operand) 接收一個long值,返回一個long結果
     
BiFunction<T,U,R> R apply(T t, U u) 接收一個T類型和一個U類型對象,返回一個R類型對象結果
BinaryOperator<T> T apply(T t, T u) 接收兩個T類型對象,返回一個T類型對象結果
ToDoubleBiFunction<T,U> double applyAsDouble(T t, U u) 接收一個T類型和一個U類型對象,返回一個double
ToIntBiFunction<T,U> int applyAsInt(T t, U u) 接收一個T類型和一個U類型對象,返回一個int
ToLongBiFunction<T,U> long applyAsLong(T t, U u) 接收一個T類型和一個U類型對象,返回一個long
DoubleBinaryOperator double applyAsDouble(double left, double right) 接收兩個double值,返回一個double結果
IntBinaryOperator int applyAsInt(int left, int right) 接收兩個int值,返回一個int結果
LongBinaryOperator long applyAsLong(long left, long right) 接收兩個long值,返回一個long結果

Lambda表達式語法

  其本質上,Lambda表達式是用於實現【函數式接口】的「抽象方法」

Lambda表達式語法格式

(形參列表) -> {Lambda體}

說明:

  • (形參列表)它就是你要賦值的函數式接口的抽象方法的 (形參列表),照抄

  • {Lambda體}就是實現這個抽象方法的方法體

  • -> 稱爲Lambda操做符(減號和大於號中間不能有空格,並且必須是英文狀態下半角輸入方式)

優化:Lambda表達式能夠精簡

  • 當{Lambda體}中只有一句語句時,能夠省略{}和{;}

  • 當{Lambda體}中只有一句語句時,而且這個語句仍是一個return語句,那麼return也能夠省略,可是若是{;}沒有省略的話,return是不能省略的

  • (形參列表)的類型能夠省略

  • 當(形參列表)的形參個數只有一個,那麼能夠把數據類型和()一塊兒省略,可是形參名不能省略

  • 當(形參列表)是空參時,()不能省略

ArrayList<String> list = new ArrayList<>();
list.forEach((li) -> System.out.println("li = " + li));//void forEach(Consumer<? super T> action)

方法引用

  當 Lambda 體知足一些特殊的狀況時,還能夠再簡化

    (1)Lambda體只有一句語句,而且是經過調用一個對象的/類的現有的方法來完成的

    (2)而且Lambda表達式的形參正好是給該方法的實參

  方法引用的語法格式:

    (1)實例對象名::實例方法

    (2)類名::靜態方法

    (3)類名::實例方法

  說明:

    :: 稱爲方法引用操做符(兩個 中間不能有空格,並且必須英文狀態下半角輸入)

    Lambda表達式的形參列表,所有在Lambda體中使用上了,要麼是做爲調用方法的對象,要麼是做爲方法的實參。

    在整個Lambda體中沒有額外的數據。

構造器引用

  (1)當Lambda表達式是建立一個對象,而且知足Lambda表達式形參,正好是給建立這個對象的構造器的實參列表。

  (2) 當Lambda表達式是建立一個數組對象,而且知足Lambda表達式形參,正好是給建立這個數組對象的長度

  構造器引用的語法格式:

    類名::new

    數組類型名::new

Stream

  Stream API 提供了一種高效且易於使用的處理數據的方式。

  Stream 是 Java8 中處理集合的關鍵抽象概念,它能夠指定你但願對集合進行的多種操做,能夠執行很是複雜的查找、過濾和映射數據等操做。

  Stream 是數據渠道,用於操做數據源(集合、數組等)所存儲的元素序列。「集合指的是負責存儲數據,Stream流指的是計算,負責處理數據!」

注意

  ①Stream 本身不會存儲元素

  ②Stream 不會改變源對象。每次處理都會返回一個持有結果的新Stream。

  ③Stream 操做是延遲執行的。這意味着他們會等到須要結果的時候才執行。

Stream 的操做三個步驟:

  1- 建立 Stream:經過一個數據源(如:集合、數組),獲取一個流

  2- 中間操做:中間操做是個操做鏈,對數據源的數據進行n次處理,可是在終結操做前,並不會真正執行。

  3- 終止操做:一旦執行終止操做,就執行中間操做鏈,最終產生結果並結束Stream。

建立Stream

  一、建立 Stream方式一:經過集合

    Java8 中的 Collection 接口被擴展,提供了兩個獲取流的方法:

      public default Stream<E> stream() : 返回一個順序流

      public default Stream<E> parallelStream() : 返回一個並行流

  二、建立 Stream方式二:經過數組

    Java8 中的 Arrays 的靜態方法 stream() 能夠獲取數組流:

      public static <T> Stream<T> stream(T[] array): 返回一個流

     還有重載形式,可以處理對應基本類型的數組

  三、建立 Stream方式三:經過 Stream.of()

    能夠調用Stream類靜態方法 of(), 經過顯示值建立一個流。它能夠接收任意數量的參數。

      public static<T> Stream<T> of(T... values) : 返回一個順序流

  四、建立 Stream方式四:建立無限流

    可使用靜態方法 Stream.iterate() 和 Stream.generate(), 建立無限流。

      public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f):返回一個無限流

      public static<T> Stream<T> generate(Supplier<T> s) :返回一個無限流

中間操做

  多箇中間操做能夠鏈接起來造成一個流水線,除非流水線上觸發終止操做,不然中間操做不會執行任何的處理!而在終止操做時一次性所有處理,稱爲「惰性求值」。

方 法 描 述
filter(Predicate p) 篩選,接收 Lambda , 從流中排除某些元素
distinct() 去除,經過流所生成元素的equals() 去除重複元素
limit(long maxSize) 截斷流,使其元素不超過給定數量
skip(long n) 跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素不足 n 個,則返回一個空流。與 limit(n) 互補
peek(Consumer action) 接收Lambda,對流中的每一個數據執行Lambda體操做
sorted() 產生一個新流,其中按天然順序排序
sorted(Comparator com) 產生一個新流,其中按比較器順序排序
map(Function f) 接收一個函數做爲參數,該函數會被應用到每一個元素上,並將其映射成一個新的元素。
mapToDouble(ToDoubleFunction f) 接收一個函數做爲參數,該函數會被應用到每一個元素上,產生一個新的 DoubleStream。
mapToInt(ToIntFunction f) 接收一個函數做爲參數,該函數會被應用到每一個元素上,產生一個新的 IntStream。
mapToLong(ToLongFunction f) 接收一個函數做爲參數,該函數會被應用到每一個元素上,產生一個新的 LongStream。
flatMap(Function f) 接收一個函數做爲參數,將流中的每一個值都換成另外一個流,而後把全部流鏈接成一個流

終結操做

  終端操做會從流的流水線生成結果。其結果能夠是任何不是流的值,例如:List、Integer,甚至是 void。流進行了終止操做後,不能再次使用。

方法 描述
boolean allMatch(Predicate p) 檢查是否匹配全部元素
boolean anyMatch(Predicate p) 檢查是否至少匹配一個元素
boolean noneMatch(Predicate p) 檢查是否沒有匹配全部元素
Optional<T> findFirst() 返回第一個元素
Optional<T> findAny() 返回當前流中的任意元素
long count() 返回流中元素總數
Optional<T> max(Comparator c) 返回流中最大值
Optional<T> min(Comparator c) 返回流中最小值
void forEach(Consumer c) 迭代
T reduce(T iden, BinaryOperator b) 能夠將流中元素反覆結合起來,獲得一個值。返回 T
U reduce(BinaryOperator b) 能夠將流中元素反覆結合起來,獲得一個值。返回 Optional<T>
R collect(Collector c) 將流轉換爲其餘形式。接收一個 Collector接口的實現,用於給Stream中元素作彙總的方法

  Collector 接口中方法的實現決定了如何對流執行收集的操做(如收集到 List、Set、Map)。另外, Collectors 實用類提供了不少靜態方法,能夠方便地建立常見收集器實例。

Optional<T>

  爲了解決空指針異常,Optional 提供不少有用的方法,這樣咱們就不用顯式進行空值檢測。

  Optional其實是個容器:它能夠保存類型 T 的值,或者僅僅保存 null。

API

  一、如何建立Optional對象?或者說如何用Optional來裝值對象或null值

    (1)static <T> Optional<T> empty() :用來建立一個空的Optional

    (2)static <T> Optional<T> of(T value) :用來建立一個非空的Optional

    (3)static <T> Optional<T> ofNullable(T value) :用來建立一個多是空,也可能非空的Optional

  二、如何從Optional容器中取出所包裝的對象呢?

    (1)T get() :要求Optional容器必須非空

        T get()與of(T value)使用是安全的

    (2)T orElse(T other) :

        orElse(T other) 與 ofNullable(T value)配合使用,

        若是Optional容器中非空,就返回所包裝值,若是爲空,就用orElse(T other)other指定的默認值(備胎)代替

    (3)T orElseGet(Supplier<? extends T> other) :

        若是Optional容器中非空,就返回所包裝值,若是爲空,就用Supplier接口的Lambda表達式提供的值代替

    (4)<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)

        若是Optional容器中非空,就返回所包裝值,若是爲空,就拋出你指定的異常類型代替原來的NoSuchElementException

  三、其餘方法

    (1)boolean isPresent() :判斷Optional容器中的值是否存在

    (2)void ifPresent(Consumer<? super T> consumer) :

        判斷Optional容器中的值是否存在,若是存在,就對它進行Consumer指定的操做,若是不存在就不作

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

        判斷Optional容器中的值是否存在,若是存在,就對它進行Function接口指定的操做,若是不存在就不作

重要的一點是 Optional 不是 Serializable。所以,它不該該用做類的字段。

 Jackson 庫支持把 Optional 看成普通對象。也就是說,Jackson會把空對象看做 null,而有值的對象則把其值看做對應域的值。

相關文章
相關標籤/搜索