兩者關系:
Lambda表達式就是函數式接口(FunctionalInterface)實現的快捷方式,它相當於函數式接口實現的實例,因為在方法中可以使用Object作為參數,所以把Lambda表達式作為方法的參數也是可以的。
函數式接口只有一個抽象方法,並且沒有重寫Object類中的方法(Object類中的public的方法除外),可以有默認方法和靜態方法。(即有且只有一個抽象方法的接口)
函數式接口一般用注解@FunctionalInterface標注。
例子:
1、聲明一個函數式接口
@FunctionalInterface public interface Calculator { double calculate(int a, int b); }
2、使用Lambda表達式(參數類型可省略)
Calculator division = (int a, int b) -> (double) a / b; System.out.println(division.calculate(5, 2)); // prints 2.5
另一個例子(使用jdk標准庫內的函數式接口,下滑至文末查看更多):
Function<Integer, Integer> selfIncrease = x -> x + 1; Function<Integer, Integer> twiceValue = x -> 2*x; Consumer<Integer> printNum = x -> System.out.println("2x+1:"+selfIncrease.apply(x)); int [] numbers= {1, 2, 3}; Arrays.stream(numbers).boxed().map(twiceValue).forEach(printNum); System.out.println("通過表達式后的數組:"+Arrays.toString(numbers));
輸出:
2x+1:3
2x+1:5
2x+1:7
通過表達式后的數組:[1, 2, 3]
3、使用Lambda表達式作為方法參數
public static void main(String[] args) throws Exception { execute(a -> String.valueOf(a + 1), 10); } public static void execute(Function<Integer, String> func, int num) { System.out.println(func.apply(num)); }
4、問題
- 標准庫內沒有提供支持更多參數的函數式接口
- lambda表達式中引用到的變量需要實際是final
// 編譯通過 public static void main(String[] args) throws Exception { int num = 10; Function<Integer, Integer> lambda = x -> x + num; } // 編譯錯誤 public static void main(String[] args) throws Exception { int num = 10; num += 1; Function<Integer, Integer> lambda = x -> x + num; }
5、函數式接口
http://www.cnblogs.com/IcanFixIt/p/4284418.html
函數式接口 |
描述 |
Function |
傳遞一個參數返回一個結果。這個結果的類型可以與參數的類型不相同。 |
BiFunction |
傳遞兩個參數返回一個結果。這個結果的類型可以與任一參數的類型不相同。 |
UnaryOperator |
代表一個操作符的操作,它的返回結果類型與操作符的類型一樣。實際上它可以被看作是Function 它的返回結果跟參數一樣,它是Function 的子接口。 |
BiOperator |
代表兩個操作符的操作,它的返回結果類型必須與操作符相同。 |
Predicate |
傳遞一個參數,基於參數的值返回boolean值。 |
Supplier |
代表一個供應者的結果。 |
Consumer |
傳遞一個參數但沒有返回值。 |
具體使用可以查看jdk源碼里的抽象方法的方法返回值,方法參數,以及函數式接口定義說明。