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體}中只有一句語句時,而且這個語句仍是一個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體中使用上了,要麼是做爲調用方法的對象,要麼是做爲方法的實參。
(2) 當Lambda表達式是建立一個數組對象,而且知足Lambda表達式形參,正好是給建立這個數組對象的長度
構造器引用的語法格式:
類名::new
數組類型名::new
Stream API 提供了一種高效且易於使用的處理數據的方式。
Stream 是 Java8 中處理集合的關鍵抽象概念,它能夠指定你但願對集合進行的多種操做,能夠執行很是複雜的查找、過濾和映射數據等操做。
Stream 是數據渠道,用於操做數據源(集合、數組等)所存儲的元素序列。「集合指的是負責存儲數據,Stream流指的是計算,負責處理數據!」
注意:
②Stream 不會改變源對象。每次處理都會返回一個持有結果的新Stream。
③Stream 操做是延遲執行的。這意味着他們會等到須要結果的時候才執行。
Stream 的操做三個步驟:
1- 建立 Stream:經過一個數據源(如:集合、數組),獲取一個流
3- 終止操做:一旦執行終止操做,就執行中間操做鏈,最終產生結果並結束Stream。
一、建立 Stream方式一:經過集合
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>
四、建立 Stream方式四:建立無限流
可使用靜態方法 Stream.iterate() 和 Stream.generate(), 建立無限流。
public static<T> Stream<T>
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 的值,或者僅僅保存 null。
一、如何建立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)配合使用,
(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,而有值的對象則把其值看做對應域的值。