【Java8新特性】Lambda表達式
一、Lambda 表達式 是什么?
Lambda讀音:拉姆達。
- Lambda是一個匿名函數,匿名函數就是一個沒有名字的函數。
- Lambda 允許把函數作為一個方法的參數(函數作為參數傳遞進方法中)。
- Lambda 表達式可以使代碼變的更加簡潔緊湊。
語法
lambda 表達式的語法格式如下:
(parameters) -> expression
或
(parameters) ->{ statements; }
Java8 中引入了一個新的操作符 "->", 該操作符稱為箭頭操作符或 Lambda 操作符。
箭頭操作符將 Lambda 表達式拆分成兩部分:
左側 : Lambda 表達式的參數。
右側 : Lambda 表達式中所需執行的操作, 即 Lambda 體。
lambda表達式的重要特征:
- 可選類型聲明:不需要聲明參數類型,編譯器可以統一識別參數值。
- 可選的參數圓括號:一個參數無需定義圓括號,但多個參數需要定義圓括號。
- 可選的大括號:如果主體只有一個語句,可以不需要使用大括號。
- 可選的返回關鍵字:如果主體只有一個表達式返回值則編譯器會自動返回值,大括號需要指定表達式返回了一個數值。
二、Lambda 表達式實例
Lambda 表達式的簡單例子:
// 1. 無參數,無返回值
() -> System.out.print("Hello Lambda");
// 2. 無參數,有返回值,返回值 5
() -> 5;
// 3. 一個參數(箭頭左側括號可以省略),返回“參數+1”后的值
x -> x + 1
// 4. 兩個參數(多個參數時,箭頭左側括號不可以省略),返回它們的差值
(x, y) -> x - y
// 5. 三個int型整數(支持多個參數),返回它們的和
(int x, int y, int z) -> x + y + z
// 6. 接收一個 string 對象,并在控制臺打印,不返回任何值(大括號可以省略)
(String s) -> System.out.print(s)
或
(String s) -> { System.out.print(s); }
注 : Lambda 表達式中的參數類型都是由編譯器推斷得出的。 Lambda 表達式中無需指定類型,程序依然可以編譯,這是因為 javac 根據程序的上下文,在后臺推斷出了參數的類型。 Lambda 表達式的類型依賴于上下文環境,是由編譯器推斷出來的,這就是所謂的 “類型推斷”。
三、函數式接口(function interface)
Lambda 表達式需要 “函數式接口” 的支持。
函數式接口 : 接口中只有一個抽象方法的接口,稱為函數式接口,可以通過 Lambda 表達式來創建該接口的對象。
可以使用 @FunctionalInterface 注解來檢查該接口是否為函數式接口,同時 javadoc 也會包含一條聲明,說明這個接口是一個函數式接口,可以有效避免其它開發人員在該接口中新增額外的方法。
簡單示例
接口:
//自定義函數式接口
@FunctionalInterface
public interface MyFun {
void run();
}
應用:
public static void main(String[] args) {
//jdk8之前
testMyFun(new MyFun() {
@Override
public void run() {
System.out.println("這是自定義函數接口");
}
});
//java8使用lambada表達式,代碼更簡潔
testMyFun(() -> System.out.println("這是自定義函數接口"));
}
private void testMyFun(MyFun myFun) {
myFun.run();
}
四、java8四大內置核心函數式接口
java8為我們定義好了4類內置函數式接口,這4類接口基本能夠滿足平時的開發需要,如果有比較特殊的情況我們可以自己去定義函數式接口。
1、consumer
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
}
應用示例:
public static void main(String[] args) {
consumTest(1000,x-> System.out.println("消費了:"+x+"元"));
}
public void consumTest(int money, Consumer consumer){
consumer.accept(money);
}
2、Supplier
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
應用示例:
public static void main(String[] args) {
int i = supplyTest(() -> (int) (Math.random() * 10););
System.out.println("獲得的隨機數是:"+i);
}
public int supplyTest(Supplier<Integer> supplier){
return supplier.get();
}
3、Function<T, R> 函數型接口,有入參,有返回值
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
應用示例:計算一個數的2倍,并輸出結果
public static void main(String[] args) {
int num = functionTest(5, x -> x * 2);
System.out.println("計算后的結果值是:"+num);
}
public int functionTest(int a,Function<Integer,Integer> function){
return function.apply(a);
}
4、Predicate
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
}
應用示例:判斷一個數是否大于10,并輸出真假
public static void main(String[] args) {
boolean flag = predicateTest(20, x -> x > 10);
System.out.println("20比10大嗎:"+ flag);
}
public boolean predicateTest(int x,Predicate<Integer> predicate){
return predicate.filter(x);
}

浙公網安備 33010602011771號