Java基礎(1)|Java8新特性
目錄- Java基礎(1)|Java8新特性
- 1、Lambda運算式
- 1.1、背景
- 1.2、目的
- 1.3、語法結構
- 1.4、‘::’用法
- 2、Stream流執行機制
- 2.1、生成流
- 3、末尾
- 1、Lambda運算式
1、Lambda運算式
Lambda運算式是JDK8推出一個重要的新特性,本質只是一個”語法糖”
1.1、背景
Java中萬物皆物件,函式無法獨立存在,只能依賴于物件來呼叫,在函式式編程語言中,函式是一等公民,它們可以獨立存在,你可以將其賦值給一個變數,或將他們當做引數傳給其他函式,JavaScript 就是函式式編程語言最典型的代表,
函式式語言提供了一種強大的功能——閉包(是一個可呼叫的物件,它記錄了一些資訊),因此Java 現在提供的最接近閉包的概念便是 Lambda 運算式,雖然閉包與 Lambda 運算式之間存在顯著差別,但至少 Lambda 運算式是閉包很好的替代者,
1.2、目的
取代大部分的匿名內部類,極大地優化代碼結構
1.3、語法結構
(parameters) -> expression
或
(parameters) ->{ statements; }
- ():引數串列
- {}:方法體
- ->:ambda運算子(讀作goes to)
- parameters:引數集合
- expression:運算式
- statements:代碼塊
結構說明如下:
- 一個 Lambda 運算式可以有零個或多個引數
- 引數的型別既可以明確宣告,也可以根據背景關系來推斷,例如:
(int a)與(a)效果相同 - 所有引數需包含在圓括號內,引數之間用逗號相隔,例如:
(a, b)或(int a, int b)或(String a, int b, float c) - 空圓括號代表引數集為空,例如:
() -> 42 - 當只有一個引數,且其型別可推導時,圓括號
()可省略,例如:a -> return a*a - Lambda 運算式的主體可包含零潭訓多條陳述句
- 如果 Lambda 運算式的主體只有一條陳述句,花括號
{}可省略,匿名函式的回傳型別與該主體運算式一致 - 如果 Lambda 運算式的主體包含一條以上陳述句,則運算式必須包含在花括號{}中(形成代碼塊),匿名函式的回傳型別與代碼塊的回傳型別一致,若沒有回傳則為空
Lambda運算式重要特征
- 可選型別宣告:不需要宣告引數型別,編譯器可以統一識別引數值,
- 可選的引數圓括號:一個引數無需定義圓括號,但多個引數需要定義圓括號,
- 可選的大括號:如果主體包含了一個陳述句,就不需要使用大括號,
- 可選的回傳關鍵字:如果主體只有一個運算式回傳值則編譯器會自動回傳值,大括號需要指定明運算式回傳了一個數值,
Lambda運算式使用要求
Lambda 規定介面中只能有一個需要被實作的方法(即只能有一個抽象方法),不是規定介面中只能有一個方法,這也稱之為“函式式介面”
注意:jdk 8 中有另一個新特性:default, 被 default 修飾的方法會有默認實作,不是必須被實作的方法,所以不影響 Lambda 運算式的使用,
而想定義函式式介面需要使用@FunctionalInterface注解,要求介面中的抽象方法只有一個,如果你嘗試添加第二個抽象方法,將拋出編譯時錯誤,這個注解往往會和 lambda 運算式一起出現,
用法:
// 1. 不需要引數,回傳值為 5
() -> 5
// 2. 接收一個引數(數字型別),回傳其2倍的值
x -> 2 * x
// 3. 接受2個引數(數字),并回傳他們的差值
(x, y) -> x – y
// 4. 接收2個int型整數,回傳他們的和
(int x, int y) -> x + y
// 5. 接受一個 string 物件,并在控制臺列印,不回傳任何值(看起來像是回傳void)
(String s) -> System.out.print(s)
// 介面方法多個引數、有回傳值、需要多行代碼時
(name,age) -> {
System.out.print(name);
return name + “ :” + age;
}
1.4、‘::’用法
- run(Class::staticMethod)靜態方法參考
- run(new Class()::Method) 非靜態(普通方法參考)
- run(Class::new) 構造方法參考
2、Stream流執行機制
2.1、生成流
1、appleStore.stream();
2、Arrays.stream(new int[]{});
3、Stream.of(1,2,3,4);
流的不可重復使用(流是針對每一個元素進行流水線式執行)
public static void main(String[] args) {
//流的不可重復使用
Stream<Apple> stream1 = appleStore.stream();
Stream<Apple> stream2 = stream1.filter(a -> a.getColor().equals("red"));
//stream是每次經過一次流傳遞后,前面的流就關閉了,是嚴格按照順序執行的
//Exception:stream has already been operated upon or closed
Stream<Apple> stream3 = stream1.filter(apple -> apple.getWeight() > 100);
}
圖中綠色節點為中間節點,可以擁有多個,并且是懶節點,遇到終值節點才會執行
紅色為終值節點,只有一個,而且要放在流水線最后

3、末尾
關于函式式介面的應用
對未知json回傳形式介面資料做必要處理
protected <T> T doCall(JSONObject jsonObject, AbstractCallBack<T> abstractCallBack) {
T result = null;
if (jsonObject != null) {
if (jsonObject.containsKey(ERROR_CODE) && jsonObject.getInteger(ERROR_CODE) != 0) {
String errorCode = jsonObject.getString(ERROR_CODE);
String errorMsg = jsonObject.getString(ERROR_MSG);
try {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
log.warn("微信回傳例外errcode:[{}],errmsg:[{}],當前方法:[{}],呼叫者:[{}]", errorCode, errorMsg, stackTraceElements[2].toString(), stackTraceElements[3].toString());
} catch (Exception e) {
log.warn("微信回傳例外并未獲取到呼叫者:errcode:[{}],errmsg:[{}]", errorCode, errorMsg);
}
return null;
} else {
result = abstractCallBack.execute(jsonObject);
}
}
return result;
}
/**
* 回呼執行方法
*
* @param <T>
*/
@FunctionalInterface
public interface AbstractCallBack<T> {
/**
* 回呼
*
* @param jsonObject
* @return
*/
T execute(JSONObject jsonObject);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/429238.html
標籤:Java
