以前寫了有關JDK8的Lambda表達式:java代碼之美(1)---Java8 Lambdahtml
函數式接口能夠理解就是爲Lambda服務的,它們組合在一塊兒可讓你的代碼看去更加簡潔。java
概念
所謂的函數式接口, 固然首先是一個接口, 而後就是在這個接口裏面 只能有一個抽象方法。編程
有關函數式接口,有個專門的註解叫:@FunctionalInterface
。該註解主要特色有:ide
一、該註解只能標記在"有且僅有一個抽象方法"的接口上,表示函數式接口。 二、JDK8接口中的靜態方法和默認方法,都不算是抽象方法。 三、接口默認繼承 java.lang.Object,因此若是接口顯示聲明覆蓋了Object中的方法,那麼也不算抽象方法。 四、容許java.lang.Object中的public方法 五、該註解不是必須的,若是一個接口符合"函數式編程"定義,那麼加不加該註解都沒有影響。加上該註解可以 更好地讓編譯器進行檢查, 若是編寫的不是函數式接口,可是加上了@FunctionalInterface 那麼編譯器會報錯。
1) 正確示例函數式編程
/** * 函數式接口註解 */ @FunctionalInterface public interface PersonInterface { /** * 一、僅有一個抽象方法 */ void say(); /** * 二、java.lang.Object中的方法不算 */ @Override boolean equals(Object var1); /** * 三、java8 接口才能夠有默認的方法實現 前提是方法名稱必須使用default關鍵字修飾 */ default void defaultMethod() { System.out.println("haha"); } /** * 四、靜態方法 */ static void staticMethod() { } }
2) 錯誤示例函數
加上@FunctionInterface,就表明該接口是函數式接口,只能有一個抽象方法,若是有多個編譯時就會直接報錯。測試
其實這個問題很好去理解,上面說了函數式接口主要是爲Lambda語法服務的,爲了讓代碼看去更加簡潔。3d
下面經過示例來講明code
public static void main(String[] args) { //上面的接口 經過Lambda表達式從新 say方法 PersonInterface inter = () -> System.out.println("我說什麼好呢?"); inter.say(); //控制檯輸出: 我說什麼好呢? }
經過 函數式接口 + Lambda表達式 讓代碼看去變的簡潔,而這裏的關鍵點在於:htm
()->{} 就是表明對say()方法的重寫
若是你有個多個抽象方法, 那麼()-> {} 這種寫法,編譯器就不知道這是重寫的哪一個方法了。因此這就是爲何只能有一個抽象方法的緣由。
這裏再舉一個綜合示例,來方便理解它們。
自定義函數式接口
/** * 自定義函數TestFunction,提供handler接口, 傳入的是A,返回的是B */ @FunctionalInterface public interface MyFunction<A, B> { /** * @Description: 傳入的是A 返回的是B */ B handler(A a, A a1); }
Student對象
public class Student { /** * 姓名 */ private String name; /** * 年齡 */ private Integer age; //省略 set get toString 全參數構造函數 無參構造函數 }
測試類
public static void main(String[] args) { //一、求和 傳入Integer返回Integer類型 MyFunction<Integer, Integer> myFunction1 = (x, y) -> { //返回總和 return x + y; }; Integer count = myFunction1.handler(5, 10); System.out.println("輸出總和爲:" + count); //二、求和 傳入Integer返回String類型 MyFunction<Integer, String> myFunction2 = (x, y) -> { //返回總和 return x + " + " + y + " = " + (x + y); }; System.out.println(myFunction2.handler(5, 10)); //三、對象處理 過濾對象 List<Student> students = Arrays.asList(new Student("小明", 3), new Student("小白", 13), new Student("小黃", 18)); MyFunction<Integer, List<Student>> myFunction3 = (x, y) -> { //這裏經過java8 的stream來過濾 年齡大於x 且小於y的對象 List<Student> studentList = students.stream().filter(student -> student.getAge() > x && student.getAge() < y).collect(Collectors.toList()); return studentList; }; List<Student> list = myFunction3.handler(5, 15); //遍歷集合 輸出對象 list.forEach(x -> System.out.println(x)); }
運行結果
從運行結果能夠很明顯看出,集合對象通過過濾只剩下一個知足條件的了。
你若是願意有所做爲,就必須善始善終。(24)