java8 新特性之函式式介面
函式式介面介紹(摘自菜鳥):
函式式介面(Functional Interface)就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的介面。
函式式介面可以被隱式轉換為 lambda 表示式。
Lambda 表示式和方法引用(實際上也可認為是Lambda表示式)上。
如定義了一個函式式介面如下:
@FunctionalInterfaceinterface GreetingService { void sayMessage(String message); }
那麼就可以使用Lambda表示式來表示該介面的一個實現(注:JAVA 8 之前一般是用匿名類實現的):
GreetingService greetService1 = message -> System.out.println("Hello " + message);
java.util.function 它包含了很多類,用來支援 Java的 函數語言程式設計,該包中的函式式介面有(對於英文不好的我,這個表格也算是照抄下來了):
序號 | 介面 & 描述 |
---|---|
1 |
BiConsumer<T,U>
代表了一個接受兩個輸入引數的操作,並且不返回任何結果 |
2 |
BiFunction<T,U,R>
代表了一個接受兩個輸入引數的方法,並且返回一個結果 |
3 |
BinaryOperator<T>
代表了一個作用於於兩個同型別運算子的操作,並且返回了運算子同型別的結果 |
4 |
BiPredicate<T,U>
代表了一個兩個引數的boolean值方法 |
5 |
BooleanSupplier
代表了boolean值結果的提供方 |
6 |
Consumer<T>
代表了接受一個輸入引數並且無返回的操作 |
7 |
DoubleBinaryOperator
代表了作用於兩個double值運算子的操作,並且返回了一個double值的結果。 |
8 |
DoubleConsumer
代表一個接受double值引數的操作,並且不返回結果。 |
9 |
DoubleFunction<R>
代表接受一個double值引數的方法,並且返回結果 |
10 |
DoublePredicate
代表一個擁有double值引數的boolean值方法 |
11 |
DoubleSupplier
代表一個double值結構的提供方 |
12 |
DoubleToIntFunction
接受一個double型別輸入,返回一個int型別結果。 |
13 |
DoubleToLongFunction
接受一個double型別輸入,返回一個long型別結果 |
14 |
DoubleUnaryOperator
接受一個引數同為型別double,返回值型別也為double 。 |
15 |
Function<T,R>
接受一個輸入引數,返回一個結果。 |
16 |
IntBinaryOperator
接受兩個引數同為型別int,返回值型別也為int 。 |
17 |
IntConsumer
接受一個int型別的輸入引數,無返回值 。 |
18 |
IntFunction<R>
接受一個int型別輸入引數,返回一個結果 。 |
19 |
IntPredicate
:接受一個int輸入引數,返回一個布林值的結果。 |
20 |
IntSupplier
無引數,返回一個int型別結果。 |
21 |
IntToDoubleFunction
接受一個int型別輸入,返回一個double型別結果 。 |
22 |
IntToLongFunction
接受一個int型別輸入,返回一個long型別結果。 |
23 |
IntUnaryOperator
接受一個引數同為型別int,返回值型別也為int 。 |
24 |
LongBinaryOperator
接受兩個引數同為型別long,返回值型別也為long。 |
25 |
LongConsumer
接受一個long型別的輸入引數,無返回值。 |
26 |
LongFunction<R>
接受一個long型別輸入引數,返回一個結果。 |
27 |
LongPredicate
R接受一個long輸入引數,返回一個布林值型別結果。 |
28 |
LongSupplier
無引數,返回一個結果long型別的值。 |
29 |
LongToDoubleFunction
接受一個long型別輸入,返回一個double型別結果。 |
30 |
LongToIntFunction
接受一個long型別輸入,返回一個int型別結果。 |
31 |
LongUnaryOperator
接受一個引數同為型別long,返回值型別也為long。 |
32 |
ObjDoubleConsumer<T>
接受一個object型別和一個double型別的輸入引數,無返回值。 |
33 |
ObjIntConsumer<T>
接受一個object型別和一個int型別的輸入引數,無返回值。 |
34 |
ObjLongConsumer<T>
接受一個object型別和一個long型別的輸入引數,無返回值。 |
35 |
Predicate<T>
接受一個輸入引數,返回一個布林值結果。 |
36 |
Supplier<T>
無引數,返回一個結果。 |
37 |
ToDoubleBiFunction<T,U>
接受兩個輸入引數,返回一個double型別結果 |
38 |
ToDoubleFunction<T>
接受一個輸入引數,返回一個double型別結果 |
39 |
ToIntBiFunction<T,U>
接受兩個輸入引數,返回一個int型別結果。 |
40 |
ToIntFunction<T>
接受一個輸入引數,返回一個int型別結果。 |
41 |
ToLongBiFunction<T,U>
接受兩個輸入引數,返回一個long型別結果。 |
42 |
ToLongFunction<T>
接受一個輸入引數,返回一個long型別結果。 |
43 |
UnaryOperator<T>
接受一個引數為型別T,返回值型別也為T。 |
程式碼示例:
菜鳥教程的示例略
BiConsumer<T,U>
代表了一個接受兩個輸入引數的操作,並且不返回任何結果
// 想不到更好的示例了,就測試一下 BiConsumer 應該一次性單獨邏輯,不依賴的eval2(list, (k,v) -> {System.out.println("傳入的引數1為:"+k + " 傳入的引數2為:"+v);});public static void eval2(List<Integer> list, BiConsumer<Integer,String> biConsumer) { for(Integer n: list) {biConsumer.accept(n,"pa2");} }
輸出結果為:
傳入的引數1為:1 傳入的引數2為:pa2 傳入的引數1為:2 傳入的引數2為:pa2 傳入的引數1為:3 傳入的引數2為:pa2 傳入的引數1為:4 傳入的引數2為:pa2 傳入的引數1為:5 傳入的引數2為:pa2 傳入的引數1為:6 傳入的引數2為:pa2 傳入的引數1為:7 傳入的引數2為:pa2 傳入的引數1為:8 傳入的引數2為:pa2 傳入的引數1為:9 傳入的引數2為:pa2
BinaryOperator<T>
代表了一個作用於於兩個同型別運算子的操作,並且返回了運算子同型別的結果
// 代表了一個作用於於兩個同型別運算子的操作,並且返回了運算子同型別的結果 // 邏輯處理,並返回與引數型別一樣的結果eval3(list, (k,v) -> v+k);public static void eval3(List<Integer> list, BinaryOperator<String> binaryOperator) { for(Integer n: list) {System.out.println(binaryOperator.apply(String.valueOf(n),"abc"));} }
這個方法泛型只有一個,卻要傳遞兩個引數。結果如下:
abc1 abc2 abc3 abc4 abc5 abc6 abc7 abc8 abc9
BiPredicate<T,U>
代表了一個兩個引數的boolean值方法
// BiPredicate<T,U> 方法介紹:代表了一個兩個引數的boolean值方法// 處理邏輯並返回boolean型別,可穿兩個不同型別引數。eval4(list, (k,v) -> v.length()==k);public static void eval4(List<Integer> list, BiPredicate<Integer,String> biPredicate) { for(Integer n: list) {System.out.println(biPredicate.test(n,"213"));} }
這個可以傳入兩個不同的型別進行對比,返回boolean型別。結果如下:
falsefalsetruefalsefalsefalsefalsefalsefalse
BiFunction<T,U,R>
代表了一個接受兩個輸入引數的方法,並且返回一個結果
// BiFunction<T,U,R> 代表了一個接受兩個輸入引數的方法,並且返回一個結果// 三個型別都可自定義,相當於處理兩個引數後返回結果。eval5(list, (k,v) -> v.length()==k);public static void eval5(List<Integer> list, BiFunction<Integer,String,Boolean> biFunction) { for(Integer n: list) {System.out.println(biFunction.apply(n,"213"));} }
結果如下:
falsefalsetruefalsefalsefalsefalsefalsefalse
程式碼沒有具體含義,只是學習一下,其實只要看幾個大概就能理解這個函式式介面的大概邏輯了。
有一些自帶的函式式介面,除了唯一的一個抽象方法,還有一些預設方法,還是很好的。可以看下原始碼,暫時無業務需求。
貼上完整的練習程式碼如下:
寫完函式式介面,有個疑問函式式介面和抽象類有啥區別?除了介面和函式的區別,還有那些區別。以下摘自知乎,還不是很能說服自己。
在 java 8 之前,介面與其實現類之間的 耦合度 太高了( tightly coupled),當需要為一個介面新增方法時,所有的實現類都必須隨之修改。預設方法解決了這個問題,它可以為介面新增新的方法,而不會破壞已有的介面的實現。這在 lambda 表示式作為 java 8 語言的重要特性而出現之際,為升級舊介面且保持向後相容(backward compatibility)提供了途徑。
- 介面可以被類多實現(被其他介面多繼承),抽象類只能被單繼承。
- 介面中沒有
this
,沒有建構函式,不能擁有例項欄位(例項變數)或例項方法,無法儲存 狀態( state),抽象方法中可以。 - 抽象類不能在 java 8 的 lambda 表示式中使用。
- 從設計理念上,介面反映的是 “like-a” 關係,抽象類反映的是 “is-a” 關係。
作者:魔王不造反
連結:
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
摘自菜鳥教程的評論
函式式介面裡是可以包含靜態方法,因為靜態方法不能是抽象方法,是一個已經實現了的方法,所以是符合函式式介面的定義的;
3、 函式式介面裡允許定義 java.lang.Object 裡的 public 方法
函式式介面裡是可以包含Object裡的public方法,這些方法對於函式式介面來說,不被當成是抽象方法(雖然它們是抽象方法);因為任何一個函式式介面的實現,預設都繼承了 Object 類,包含了來自 java.lang.Object 裡對這些抽象方法的實現;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69992808/viewspace-2750554/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java8新特性探索之函式式介面Java函式
- Java8的新特性--函式式介面Java函式
- java8特性-函式式介面Java函式
- Java8新特性-四大核心函式式介面Java函式
- java8新特性之函式式介面、lambda表示式、介面的預設方法、方法和建構函式的引用Java函式
- JDK8新特性之函式式介面JDK函式
- ?Java8新特性之Lambda表示式,函式式介面,方法引用和default關鍵字Java函式
- Java8之Stream-函式式介面Java函式
- 【Java8新特性】還沒搞懂函式式介面?趕快過來看看吧!Java函式
- java8 新特性之Lambda 表示式Java
- 簡析JAVA8函式式介面Java函式
- 「Java8系列」神奇的函式式介面Java函式
- Java8新特性探索之Stream介面Java
- java8 函式式介面——Function/Predict/Supplier/ConsumerJava函式Function
- PHP新特性之閉包、匿名函式PHP函式
- PHP 7.4 新特性之箭頭函式PHP函式
- Java8新特性(一)-Lambda表示式Java
- Java8新特性(1):Lambda表示式Java
- java8的新特性之lambda表示式和方法引用Java
- JDK1.8新特性:Lambda表示式語法和內建函式式介面JDK函式
- 【java8新特性】蘭姆達表示式Java
- oracle 21c 新特性之 CHECKSUM 分析函式Oracle函式
- 好程式設計師分享java8新特性之Lambda表示式程式設計師Java
- java8特性-lambda表示式Java
- Java8新特性——從Lambda表示式到Stream流Java
- 函式式介面函式
- Java8新特性之:OptionalJava
- java-反射,介面新特性,Lambda表示式Java反射
- Java8學習系列之匿名函式LambdaJava函式
- PHP 7.4 新特性 —— 箭頭函式 2.0PHP函式
- Java函式式介面Java函式
- ?Java8新特性之Optional類Java
- java8 新特性之方法引用Java
- java8 新特性之Optional 類Java
- JDK 1.8 新特性之Lambda表示式JDK
- Java8新特性之時間APIJavaAPI
- java8 新特性之預設方法Java
- JDK1.8新特性之Lambda表示式JDK