更新時間:2020-10-20 17:55:46 來源:動力節點 瀏覽1128次
函數式接口,即適用于函數式編程場景的接口。而Java中的函數式編程體現就是Lambda,所以函數式接口就是可以適用于Lambda使用的接口。只有確保接口中有且僅有一個抽象方法,Java中的Lambda才能順利地進行推導。
“語法糖”是指使用更加方便,但是原理不變的代碼語法。例如在遍歷集合時使用的for-each語法,其實底層的實現原理仍然是迭代器,這便是“語法糖”。從應用層面來講,Java中的Lambda可以被當做是匿名內部
類的“語法糖”,但是二者在原理上是不同的。
格式:只要確保接口中有且僅有一個抽象方法即可:
修飾符 interface 接口名稱 {
public abstract 返回值類型 方法名稱(可選參數信息);
// 其他非抽象方法內容
}
@FunctionalInterface注解
與@Override 注解的作用類似,Java 8中專門為函數式接口引入了一個新的注解: @FunctionalInterface 。該注解可用于一個接口的定義上,一旦使用該注解來定義接口,編譯器將會強制檢查該接口是否確實有且僅有一個抽象方法,否則將會報錯。需要注意的是,即使不使用該注解,只要滿足函數式接口的定義,這仍然是一個函數式接口,使用起來都一樣。
自定義函數式接口(前面已經寫過,這就不重復寫了)
package com.wzlove.function;
/**
自定義函數式接口
使用@FunctionalInterface可以說明該接口是函數式接口,但是不加,如果接口中只有一個抽象方法,這個接口也是函數式接口
也就是說函數式接口不以注解的存在而存在
*/
@FunctionalInterface
public interface MyFunctionalInterface {
public abstract void show();
}
lambda表達式: (參數列表)->{代碼}
lambda表達式(前面有篇文章說過,不詳細說明)
有參數,有返回值的自定義函數式接口
@FunctionalInterface
public interface Sumable {
int sum(int a, int b);
}
JDK1.8之后的某些函數式接口
supplier生產數據函數式接口,目的是生產數據。
目前好像看不出來有什么用,但是好像和jdk8的Stream流有關。舉個小例子
package com.wzlove.supplier;
import java.util.function.Supplier;
/**
* 使用supplier函數式接口求數組的最大值
*/
public class ArrMaxValue {
public static int getMaxValue(Supplier
return sup.get();
}
public static void main(String[] args) {
// 創建數組
int[] arr = {100,20,50,30,99,101,-50};
int maxValue = getMaxValue(()->{
int max = arr[0];
for (int i : arr) {
if(i > max){
max = i;
}
}
return max;
});
System.out.println("數組中的最大值為:" + maxValue);
}
}
Consumer消費數據函數式接口
這個方法是用來消費數據的,如何消費,消費規則自己定義.
java.util.function.Supplier 接口僅包含一個無參的方法: T get() 。用來獲取一個泛型參數指定類型的對
象數據。由于這是一個函數式接口,這也就意味著對應的Lambda表達式需要“對外提供”一個符合泛型類型的對象
數據。
package com.wzlove.comsumer;
import java.util.function.Consumer;
/**
* 使用Consumer函數式接口實現格式化輸出
*/
public class ConsumerDemo2 {
public static void printInfo(String[] strArr, Consumer
for (int i = 0; i < strArr.length; i++) {
con1.andThen(con2).accept(strArr[i]);
}
}
public static void main(String[] args) {
String[] strArr = {"迪麗熱巴,女","鄭爽,女","楊紫,女"};
printInfo(strArr,(message)->{
System.out.print("姓名:" + message.split(",")[0] + "。 ");
},(message)->{
System.out.println("性別:" + message.split(",")[1] + "。");
});
}
}
Predicate判斷函數式接口
Predicate 接口中包含一個抽象方法: boolean test(T t) 。用于條件判斷的場景
默認方法:
default Predicate and(Predicate other) : 將兩個Predicate 條件使用“與”邏輯連接起來實現“并且”的效果
default Predicate or(Predicate other) : or 實現邏輯關系中的“或”
default Predicate negate() : 取反
package com.wzlove.functionalinterface.predicate;
import java.util.ArrayList;
import java.util.function.Predicate;
/**
*
*/
public class PredicateDemo2 {
/**
* 檢查數組中的元素是否符合要求,滿足要求加入List中并返回
* @param arr 需要判斷的數組
* @param pre1 判斷接口1,判斷性別是否為女
* @param pre2 判斷接口2,判斷姓名長度是否大于2
* @return 集合
*/
public static ArrayList
// 創建集合
ArrayList
for (String s : arr) {
if( pre1.and(pre2).test(s)){
list.add(s);
}
}
return list;
}
public static void main(String[] args) {
// 創建數組
String[] arr = {"迪麗熱巴,女","楊洋,男","李溪芮,女","鄭爽,女"};
// 調用方法(Lambda表達式可以簡化)
ArrayList
return str.split(",")[1].equals("女");
},(str)->{
return str.split(",")[0].length() > 2;
});
// 遍歷集合
for (String elem : list) {
System.out.print(elem + " ");
}
}
}
Function類型轉換函數式接口
Function 接口中最主要的抽象方法為: R apply(T t) ,根據類型T的參數獲取類型R的結果。
Function 接口中有一個默認的andThen 方法,用來進行組合操作。
package com.wzlove.functionalinterface.function;
import java.util.function.Function;
/**
*
*/
public class FunctionDemo2 {
/**
* 將String分割,獲得第二個元素,將數據轉化為int,int數據加100,再將int轉化為String
* @param str 轉化的數據
* @param fun1 String -> String
* @param fun2 String -> Integer
* @param fun3 Integer -> String
* @return 最后的String
*/
public static String convert(String str,
Function
Function
Function
return fun1.andThen(fun2).andThen(fun3).apply(str);
}
public static void main(String[] args) {
String str = convert("迪麗熱巴,23",(s)->{
return s.split(",")[1];
},(s)->{
return Integer.parseInt(s) + 100;
},(s)->{
return String.valueOf(s);
});
System.out.println(str);
}
}
看完了上面的諸多實例,相信你對函數式接口和Lambda表達式都有了一定的了解,作為Java1.8的新特性函數式接口是目前Java接口中最需要我們學習的一個,如果你覺得還沒有完全掌握函數式接口也沒有關系,隨時可以來本站的Java基礎教程觀看學習。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習