好程式設計師分享java8新特性之Lambda表示式
好程式設計師分享java8新特性之Lambda表示式
⼀、 Lambda 表示式簡介
什麼是 Lambda?
Lambda 表示式是 Java 8 推出的⼀個新特性。從本質上講, Lambda 表示式是⼀個匿名函式。
為什麼要使⽤ Lambda?
使⽤ Lambda 表示式可以對⼀個接⼝進⾏⾮常簡潔的實現。
之前我們在給⼀個接⼝引⽤賦值的時候,可以使⽤接⼝實現類,或者匿名內部類。但是有了
Lambda 表示式,我們可以更加⽅便的實現這個需求。
interface Comparator <T > {
int compare (T o1 , T o2 );
}
class Program {
public static void main ( String [] args ) {
// 1. 使⽤接⼝實現類實現
class Impl implements Comparator < Integer > {
@Override
public int compare ( Integer o1 , Integer o2 ) {
return o1 - o2 ;
}
}
Comparator < Integer > c1 = new Impl ();
// 2. 使⽤匿名內部類實現
Comparator < Integer > c2 = new Comparator < Integer > () {
@Override
public int compare ( Integer o1 , Integer o2 ) {
return o1 - o2 ;
}
};
// 3. 使⽤ Lambda 表示式實現
Comparator < Integer > c3 = (o1 , o2 ) -> o1 - o2 ;
}
}
從上述例⼦中,我們可以看到 : 對同樣⼀個接⼝引⽤的實現, Lambda 最簡單!
Lambda 對接⼝的要求? 雖然 Lambda 表示式可以很便捷的實現接⼝,但並不是所有的接⼝都可以使⽤ Lambda 表示式來實現。
可以⽤ Lambda 表示式來簡潔實現的接⼝是有要求的。因為 Lambda 表示式本質上來講,就是⼀個匿名
函式,⽤這個匿名函式來實現接⼝中的⽅法。所以,如果接⼝中有多個必須要實現抽象⽅法時,
Lambda 表示式將⽆法是⽤。
注: Lambda 表示式要求接⼝中只有⼀個必須要實現的抽象⽅法。但是 JAVA 8 對接⼝也有⼀個
擴充。現在,我們可以在接⼝中,是⽤ default 來修飾⼀個⽅法,此時,這個⽅法需要有實
現。那麼,實現類在實現接⼝的時候,對於 default ⽅法,可以實現,也可以不實現。所以,
這⾥所說的接⼝中只有⼀個必須實現的抽象⽅法,與 default ⽅法⽆關。
@FunctionalInterface**
@FunctionalInterface
因為 Lambda 表示式要求接⼝中有且只能有⼀個必須實現的抽象⽅法,所以,對接⼝可以使⽤
@FunctionalInterface 接⼝來進⾏限定。這個註解約束了接⼝中只能有⼀個必須實現的抽象⽅
法。使⽤這個註解修飾的接⼝,⼜叫做函式式接⼝。
⼆、 Lambda 表示式基礎語法
Lambda 表示式,本質上就是⼀個匿名⽅法,所以離不開⽅法的⼏個必要的組成部分:返回值、⽅法
名、引數、⽅法體。但是由於他是⼀個匿名⽅法,所以⽅法名可以忽略。同時, Lambda 中也不需要
顯式宣告返回值型別。所以, 我們在寫 Lambda 表示式的時候,只需要關⼼引數和⽅法體即可。
引數: 以 () 包圍起來,多個引數以逗號分隔
(int a, int b)
⽅法體: 以 {} 包圍起來
{ System.out.println("hello world"); }
-> : Lambda 運算子,⽤來分隔引數和⽅法體
(int a, int b) -> {};
有了這⼏個組成部分,我們就可以對任意的函式式接⼝使⽤ Lambda 進⾏實現
// ⽆參、⽆返回值
() -> { System .out .println ( "hello world" ); };
// int, int 引數、⽆返回值
( int a , int b ) -> { System .out .println (a + b ); };
// int, int 引數、 int 返回值
( int a , int b ) -> { return a + b ; };
三、 Lambda 表示式語法精簡
接⼝中定義的⽅法,已經宣告瞭⽅法的引數型別、數量和返回值型別。所以,使⽤ Lambda 表示式在
實現的時候,對應的部分可以省略 引數精簡
1. 引數的型別可以精簡
(int a, int b) -> { System.out.println(a + b); }
可以精簡為:
(a, b) -> { System.out.println(a + b); }
2. 如果引數數量只有⼀個,⼩括號可以精簡
(int a) -> { System.out.println(a); }
可以精簡為:
a -> { System.out.println(a); }
⽅法體精簡
1. 如果⽅法體中只有⼀條語句,則⼩括號可以省略
a -> { System.out.println(a); }
可以精簡為:
a -> System.out.println(a);
2. 如果⽅法體中唯⼀的⼀條語句是返回值,在精簡掉⼤括號後, return 也必須省略
a -> { return a * 2; }
可以精簡為:
a -> a * 2;
四、 Lambda 表示式語法進階之⽅法引⽤
什麼是⽅法引⽤
如果在使⽤ Lambda 進⾏接⼝實現的時候,需要實現的邏輯已經在某⼀個⽅法中實現,則可以直接使
⽤⽅法引⽤,指向指定的⽅法。
interface Calculate {
int calculate ( int a , int b );
}
public class Program {
public static void main ( String [] args ) {
// 接⼝引⽤
Calculate c = (a , b ) -> a + b ;
}
public static int add ( int a , int b ) {
return a + b ;
}
} 在上述程式碼中, main 函式中 Calculate 引⽤ c 的實現部分,下⾯已經有⼀個⽅法 add 進⾏了實現。
所以此時,我們不需要再實現⼀次,只需要直接指向已經寫好的實現即可。所以,可以進⾏如下改
造:
Calculate c = Program ::add ;
上⾯的 Program::add 就是⼀個⽅法引⽤。引⽤了 Program 類中的⼀個靜態⽅法 add 。
在使⽤⽅法引⽤的時候需要注意
1. 引⽤的⽅法引數數量、引數型別、返回值型別必須和函式式接⼝中的⽅法定義⼀致。
2. ⽅法引⽤必須有引⽤主體,即⽅法的⾪屬者。例如:上⽅的 add ⽅法是⼀個靜態⽅法,需要使⽤
類來調⽤。所以⽅法引⽤就是 類 :: ⽅法,如果是⼀個成員⽅法,則需要使⽤ 物件 :: ⽅法 的
形式來引⽤。
構造⽅法的引⽤
如果需要引⽤⼀個構造⽅法,需要使⽤ 類 ::new 進⾏引⽤
interface CreatePerson {
Person getPerson ();
}
class Person {}
class Program {
public static void main ( String [] args ) {
CreatePerson c = Person :: new ;
}
}
五、 Lambda 表示式之綜合案例 : 排序 Comparator
// 排序
list .sort ((o1 , o2 ) -> o2 .age - o1 .age );
// 使⽤ Lambda 表示式來實現 Comparator 接⼝,並例項化⼀個 TreeSet 物件
TreeSet <Person > set = new TreeSet <> ((o1 , o2 ) -> {
if (o1 .age >= o2 .age ) {
return - 1 ;
}
else {
return 1 ;
}
});
六、 Lambda 表示式之綜合案例 : forEach() // 將集合中的每⼀個元素都帶⼊到⽅法 accept 中。
list .forEach (System .out ::println );
// 輸出集合中所有的偶數
list .forEach (ele -> {
if (ele % 2 == 0 ) {
System .out .println (ele );
}
});
七、 Lambda 表示式之綜合案例 : removeIf()
// 將集合中的每⼀個元素都帶⼊到 test ⽅法中 , 如果返回值是 true ,則刪除這個元素
// 刪除集合中的年齡⼤於 10 歲的元素
list .removeIf (ele -> ele .age > 10 );
⼋、 Lambda 表示式之綜合案例 : 執行緒例項化
new Thread (() -> {
for ( int i = 0 ; i < 100 ; i ++ ) {
System .out .println (i );
}
}).start ();
九、系統內建函式式接⼝
系統已經給我們提供了很多函式式接⼝,⽅便我們的使⽤。因此,如果我們需要⽤到以下⽅法的時
候,不需要再設計接⼝,直接使⽤指定的接⼝即可。 函式式接⼝
參
數
返回值 特殊說明:⼏個特殊實現的⼦接⼝
Predicate T boolean
IntPredicate : 引數: int ,返回值: boolean
LongPredicate : 引數: long ,返回值: boolean
DoublePredicate : 引數: double ,返回值: boolean
Consumer T void
IntConsumer : 引數: int ,返回值: void LongConsumer :
引數: int ,返回值: void DoubleConsumer : 引數: int ,返
回值: void
Function<T, R> T R
IntFunction<R> : 引數: int ,返回值: R
IntToDoubleFunction : 引數: int ,返回值: double
IntToLongFunction : 引數: int ,返回值: long
LongFunction<R> : 引數: long ,返回值: R
LongToDoubleFunction : 引數: long ,返回值: double
LongToIntFunction : 引數: long ,返回值: int
DoubleFunction<R> : 引數: double ,返回值: R
DoubleToIntFunction : 引數: double ,返回值: int
DoubleToLongFunction : 引數: double ,返回值: long
Supplier ⽆ T
BooleanSupplier : 引數:⽆,返回值: boolean
IntSupplier : 引數:⽆,返回值: int LongSupplier : 參
數:⽆,返回值: long DoubleSupplier : 引數:⽆,返回值:
double
UnaryOperator T T
IntUnaryOperator : 引數: int ,返回值: int
LongUnaryOperator : 引數: long ,返回值: long
DoubleUnaryOperator : 引數: double ,返回值: double
BinaryOperator T,
T T
IntBinaryOperator : 引數: int, int ,返回值: int
LongBinaryOperator : 引數: long, long ,返回值: long
DoubleBinaryOperator : 引數: double, double ,返回值:
double
BiPredicate<L,
R>
L,
R boolean
BiConsumer<T,
U>
T,
U void
BiFunction<T,
U, R>
T,
U R
上述接⼝中,最常⽤的是 Predicate 、 Consumer 、
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2655451/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師Java教程分享Java8.0新特性之Lambda表示式程式設計師Java
- java8 新特性之Lambda 表示式Java
- Java8 新特性之 Lambda 表示式Java
- java8新特性之lambda表示式(一)Java
- Java8新特性(1):Lambda表示式Java
- Java8新特性(一)-Lambda表示式Java
- java8的新特性之lambda表示式和方法引用Java
- java8特性-lambda表示式Java
- Java8新特性第1章(Lambda表示式)Java
- 好程式設計師大資料學習路線分享Lambda表示式程式設計師大資料
- Java8新特性——從Lambda表示式到Stream流Java
- JDK 1.8 新特性之Lambda表示式JDK
- JDK1.8新特性之Lambda表示式JDK
- JDK1.8新特性之Lambda表示式()->JDK
- jdk1.8 新特性之 lambda表示式JDK
- C++11新特性之Lambda表示式C++
- 【譯】java8之lambda表示式Java
- ?Java8新特性之Lambda表示式,函式式介面,方法引用和default關鍵字Java函式
- JDK1.8的新特性之Lambda表示式JDK
- Java8新特性 - LambdaJava
- jdk1.8 新特性之 如何寫lambda表示式JDK
- java8 lambda表示式Java
- java8新特性之函式式介面、lambda表示式、介面的預設方法、方法和建構函式的引用Java函式
- 【Java8新特性】Lambda表示式基礎語法,都在這兒了!!Java
- JDK1.8新特性--Lambda表示式JDK
- Java 8新特性(一):Lambda表示式Java
- jdk1.8新特性:Lambda表示式JDK
- .NET3.5新特性,Lambda表示式
- Java8特性詳解 lambda表示式(一):使用篇Java
- Java8新特性系列-LambdaJava
- Java8新特性系列(Lambda)Java
- 【java8新特性】蘭姆達表示式Java
- Java8特性詳解 lambda表示式(二):流式處理中的lambdaJava
- Java8的Lambda表示式Java
- JDK新特性-Lambda表示式的神操作JDK
- java-反射,介面新特性,Lambda表示式Java反射
- .net framework3.5新特性:Lambda表示式Framework
- Java8特性詳解 lambda表示式(三):原理篇Java